Rails 模型没有什么神奇的,它只是一个带有一堆预先存在的方法的普通类,
那么,问题是“我可以在类中定义方法”吗?
第 1 部分:是的,可以。
重要的区别在于您可以定义方法在课堂上 not 在一个实例中 method
例如:
class Cow
define_method "speak" do
"MOOOO"
end
end
Cow.new.speak
=> "MOOOO"
这应该可以正常工作。请注意,您是在 Cow 类上定义它的,因此您已有的任何其他 Cow 都会自动添加该方法。
第 2 部分:如果您想在实例方法中定义方法,该怎么办?
您无法从实例方法定义方法,因此您必须获取该类,并使用它来定义方法。像这样:
class Cow
def add_speak
self.class.send(:define_method, :speak) do
"MOOOO added"
end
end
end
Cow.new.speak
NoMethodError: undefined method 'speak' for #<Cow:0xb7c48530>
Cow.new.add_speak
Cow.new.speak
=> "MOOOO added"
问题解决了。精明的读者会注意到,在这个例子中我使用send(:define_method)
- 这是需要的,因为define_method
是私有的,私有方法只能被它们所在的对象访问。在这种情况下,define_method
是在类中,我们是在实例中,所以不能直接访问。
如上所述,我们将该方法直接添加到类中,因此所有其他已存在的 Cow 也将自动添加 talk 方法。
第 3 部分:如果您只想为 1 个对象而不是该类的所有对象定义方法,该怎么办?
Example:
class Cow
def add_speak_just_me
class << self
define_method "speak" do
"MOOOO added for just me"
end
end
end
end
Cow.new.speak
NoMethodError: undefined method 'speak' for #<Cow:0xb7c72b78>
c = Cow.new
c.add_speak_just_me
c.speak
=> "MOOOO added for just me" # it works, hooray
Cow.new.speak # this new cow doesn't have the method, it hasn't been automatically added
NoMethodError: undefined method `speak' for #<Cow:0xb7c65b1c>
这是如何运作的?你就掉进兔子洞吧!
读这个:http://dannytatom.me/metaid/ http://dannytatom.me/metaid/还有祝你好运。当您意识到向实例“添加方法”实际上根本没有将其添加到实例时,它会有所帮助:-)