问题描述
因此,我目前正在学习Ruby中的元编程,我想完全了解幕后发生的事情。
我遵循了一个教程,其中在自己的小型项目中包括了一些方法,这是CSV文件的导入器,我很难将手缠在其中一种方法上。
我知道Ruby中的define_method
方法可以“即时”创建方法,这很棒。现在,在本教程中,使用该方法定义了用于从类实例化对象的方法initialize
,因此基本上看起来像这样:
class Foo
def self.define_initialize(attributes)
define_method(:initialize) do |*args|
attributes.zip(args) do |attribute,value|
instance_variable_set("@#{attribute}",value)
end
end
end
end
接下来,首先在另一个类的初始化程序中,使用Foo.define_initialize(attributes)
调用此方法,其中属性是CSV文件中的标题行,例如["attr_1","attr_2",...]
,因此*args
不是提供了。
然后在下一步中循环遍历数据:
@foos = data[1..-1].map do |d|
Foo.new(*d)
end
因此,这里*d
作为*args
分别传递给initialize方法和块。
那么,当Foo.define_initialize被调用时,该方法只是“构建”用于以后对该类的调用是正确的吗? 因此,从理论上讲,我得到了一个类,该类现在具有以下方法:
def initialize(*args)
... do stuff
end
否则,它必须抛出诸如“缺少参数”之类的异常-换句话说,它只是定义该名称所暗示的方法。
我希望我已经清楚地阐明了我的问题,因为作为来自“ Rails magic” 的Rails开发人员,我真的很想了解在某些情况下幕后发生的事情:)。
感谢您的有用回复!
解决方法
简短答案,是,长答案:
首先,让我们以一种非常简单的方式开始解释元编程如何在Ruby上工作。在Ruby中,任何事物的定义都不会接近,这意味着您可以随时添加,更新或删除任何事物(实际上,几乎任何事物)的行为。因此,如果您想向Object
类添加方法,则可以删除或更新。
在您的示例中,您所做的只是更新或创建给定类的initialize
方法。请注意,initialize
不是强制性的,因为ruby会为您建立一个默认的“空白”(如果您未创建的话)。您可能会想,“如果initialize
方法已经存在,会发生什么?”答案是“没有”。我的意思是,ruby将再次重写initialize方法,新的Foo.new
调用将调用新的initialize
。