rails 模型并没有什么神奇之处,它只是一个普通的类,带有一堆预先存在的方法,
那么,问题是“我可以在一个类中定义_method”吗?
第 1 部分:可以。
重要的区别在于你可以在类中定义方法而不是在实例中方法
例如:
class Cow
define_method "speak" do
"MOOOO"
end
end
Cow.new.speak
=> "MOOOO"
这应该可以正常工作。请注意,您是在 Cow 类上定义它,因此您已经拥有的任何其他 Cows 都会自动添加该方法。
第 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 在类,我们在实例中,所以我们不能直接访问它。
尽管如此,我们将方法直接添加到类中,所以所有其他已经存在的 Cows 也会自动添加 speak 方法。
第 3 部分:如果您只想为 1 个对象而不是该类的所有对象定义方法,该怎么办?
例子:
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/,祝你好运。当您意识到向实例“添加方法”实际上根本没有将其添加到实例时,它会有所帮助:-)