通过初始化了解Ruby define_method

问题描述

因此,我目前正在学习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

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...