如果访问属性且其属性没有数据,我有一个动态加载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
有两个问题:
RedmineIssue.new :ticket_title => 'test'
初始化模型,我不希望模型调用updateProperties
,但不管怎么说。答案 0 :(得分:3)
要动态添加方法,请阅读method_missing
好文章解释了它的一些方面。
http://www.trottercashion.com/2011/02/08/rubys-define_method-method_missing-and-instance_eval.html
答案 1 :(得分: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
对哈希执行请求的操作,然后动态定义方法,以便下次它是一个直接方法调用,这意味着它更有效,因为该方法已经存在。这有点类似于Ruby自己的OpenStruct使用的method_missing
。