0

如果访问属性并且其属性没有数据,我有一个模型可以从 REST API 动态加载数据:

class Issue
  attr_accessor :ticket_title, :priority, :description
  @ticket_title
  @priority
  @description

  def priority
    if !@priority.empty?
      updateProperties()
    end
    @priority
  end
  def description
    if !@description.empty?
      updateProperties()
    end
    @description
  end
  def ticket_title
    if !@ticket_title.empty?
      updateProperties()
    end
    @ticket_title
  end

  def updateProperties
    # loads all data from REST API
  end

  def initialize (hsh = {})
      hsh.each { |key, value|
        self.instance_variable_set("@#{key}", value) 
      }
  end

end

有两个问题:

  1. 如果我用 初始化模型RedmineIssue.new :ticket_title => 'test',我不想调用模型updateProperties,但不知何故它确实如此。
  2. 有没有办法神奇地声明函数?即,如果没有真正的功能尝试运行元功能?
4

2 回答 2

3

要动态添加方法,您应该阅读method_missing.
很好的文章解释了它的一些方面。
http://www.trottercashion.com/2011/02/08/rubys-define_method-method_missing-and-instance_eval.html

于 2012-07-20T17:00:33.580 回答
1

好吧,这里有一些关于“魔法”的东西。在您的课程中,如果您希望能够通过名为get_whateverthekeyis(愚蠢的示例,我知道)的方法获取散列的任何部分,您可以使用method_missing

class Foo
  def initialize
    @h = {}
  end
  def method_missing(name, *args, &block)
    if(name =~ /\Aget_(.+)\Z/)
      #Name is valid
      sig_class.class_exec($1) do |n|
        define_method("get_"+n) {@h[n]}
      end

      @h[$1]
    elsif(name =~ /\Aset_(.+)\Z/)
      #Name is valid
      sig_class.class_exec($1) do |n|
        define_method("set_"+n) {|v| @h[n]=v}
      end

      @h[$1] = args[0]
    else
      super
    end
  end
  private
  def sig_class
    class << self
      self
    end
  end
end

当方法未定义时,它转到method_missing. 发生这种情况时,method_missing对哈希进行请求的操作,然后动态定义方法,以便下次直接调用方法,这意味着效率更高,因为方法已经存在。这有点类似于method_missingRuby 自己的 OpenStruct 使用的 。

于 2012-07-20T17:06:12.480 回答