理解 Ruby define_method 和初始化
Understanding Ruby define_method with initialize
所以,我目前正在 Ruby 学习元编程,我想完全了解幕后发生的事情。
我遵循了一个教程,在该教程中我将一些方法包含在我自己的小项目中,一个 CSV 文件的导入器,但我很难掌握所使用的其中一种方法。
我知道 Ruby 中的 define_method
方法可以“即时”创建方法,这很棒。现在,在教程中,从 class 实例化 object 的方法 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
接下来,在另一个 class 的初始化程序中,首先使用 Foo.define_initialize(attributes)
调用此方法,其中属性是 CSV 文件中的 header 行,如 ["attr_1", "attr_2", ...]
, 所以 *args
还没有提供。
然后在下一步中循环遍历数据:
@foos = data[1..-1].map do |d|
Foo.new(*d)
end
所以这里 *d
作为 *args
分别传递给初始化方法到块。
那么,当 Foo.define_initialize 被调用时,该方法只是为以后调用 class 而“构建”的,对吗?
所以我理论上得到一个 class 现在有这样的方法:
def initialize(*args)
... do stuff
end
因为否则,它必须抛出一个异常,如“缺少参数”或其他东西 - 所以,换句话说,它只是 定义 顾名思义的方法。
我希望我的问题足够清楚,因为作为来自 "Rails magic" 的 Rails 开发人员,我真的很想在某些情况下了解幕后发生的事情:)。
感谢任何有帮助的回复!
简答,是,长答:
首先,让我们开始以非常(非常)简单的方式解释元编程如何在 Ruby 上工作。在 Ruby 中,任何事物的定义永远不会关闭,这意味着您可以随时添加、更新或删除任何事物(实际上,几乎任何事物)的行为。所以,如果你想添加一个方法到 Object
class,你是允许的,删除或更新也是如此。
在您的示例中,您只是更新或创建给定 class 的 initialize
方法。请注意 initialize
不是强制性的,因为 ruby 会为您构建一个默认的“空白”,如果您没有创建的话。您可能会想,“如果 initialize
方法已经存在会怎样?”答案是“没有”。我的意思是,ruby 将再次重写初始化方法,新的 Foo.new
调用将调用新的 initialize
.
所以,我目前正在 Ruby 学习元编程,我想完全了解幕后发生的事情。
我遵循了一个教程,在该教程中我将一些方法包含在我自己的小项目中,一个 CSV 文件的导入器,但我很难掌握所使用的其中一种方法。
我知道 Ruby 中的 define_method
方法可以“即时”创建方法,这很棒。现在,在教程中,从 class 实例化 object 的方法 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
接下来,在另一个 class 的初始化程序中,首先使用 Foo.define_initialize(attributes)
调用此方法,其中属性是 CSV 文件中的 header 行,如 ["attr_1", "attr_2", ...]
, 所以 *args
还没有提供。
然后在下一步中循环遍历数据:
@foos = data[1..-1].map do |d|
Foo.new(*d)
end
所以这里 *d
作为 *args
分别传递给初始化方法到块。
那么,当 Foo.define_initialize 被调用时,该方法只是为以后调用 class 而“构建”的,对吗? 所以我理论上得到一个 class 现在有这样的方法:
def initialize(*args)
... do stuff
end
因为否则,它必须抛出一个异常,如“缺少参数”或其他东西 - 所以,换句话说,它只是 定义 顾名思义的方法。
我希望我的问题足够清楚,因为作为来自 "Rails magic" 的 Rails 开发人员,我真的很想在某些情况下了解幕后发生的事情:)。
感谢任何有帮助的回复!
简答,是,长答:
首先,让我们开始以非常(非常)简单的方式解释元编程如何在 Ruby 上工作。在 Ruby 中,任何事物的定义永远不会关闭,这意味着您可以随时添加、更新或删除任何事物(实际上,几乎任何事物)的行为。所以,如果你想添加一个方法到 Object
class,你是允许的,删除或更新也是如此。
在您的示例中,您只是更新或创建给定 class 的 initialize
方法。请注意 initialize
不是强制性的,因为 ruby 会为您构建一个默认的“空白”,如果您没有创建的话。您可能会想,“如果 initialize
方法已经存在会怎样?”答案是“没有”。我的意思是,ruby 将再次重写初始化方法,新的 Foo.new
调用将调用新的 initialize
.