我正试图理解这个功能.
我能看到的是属性和类型被传递给opal()方法.
然后type_name需要从它的值type,只要type是一个Symbol或String.否则,name调用该方法type.我想这个name方法类似于class获取type参数类的方法.
在self.class_eval我有点迷失但我的猜测是这可能是一个代码块,可能会被添加到引用的类中self.
这怎么工作我不确定.
如果有人能解释之后发生了什么,我将不胜感激self.class_eval << DEF.
def opal(attr, type)
self.ds "#{attr}_id"
type_name = (type.is_a?(Symbol) || type.is_a?(String)) ? type : type.name
self.class_eval <<DEF
def #{attr}
if defined?(@#{attr})
@#{attr}
else
@#{attr} = if self.#{attr}_id
#{type_name}.get(self.#{attr}_id)
else
nil
end
end
end
def #{attr}=(value)
self.#{attr}_id = value.key
@#{attr} = value
end
DEF
end
Run Code Online (Sandbox Code Playgroud)
之间的内容<<DEF和DEF只是一个字符串和#{ ... }该字符串像任何其他的工作.
class_eval 将导致解释器在模块的上下文中运行字符串.
所以,如果你知道什么是什么attr,type那么你可以找出正在运行的代码来向类中添加方法.
可以说,attr是"foo"和type是"Bazzle".正在运行的代码将是:
def foo
if defined?(@foo)
@foo
else
@foo = if self.foo_id
Bazzle.get(self.foo_id)
else
nil
end
end
end
def foo=(value)
self.foo_id = value.key
@foo = value
end
Run Code Online (Sandbox Code Playgroud)