Ruby: def 和 define_method 的区别
Ruby: difference between def and define_method
我目前正在学习 ruby 元编程,当我在玩弄和测试东西时,我偶然发现了一些我似乎无法找到答案的东西。假设我们有以下代码:
class Foo
end
Foo.instance_eval do
define_method("bar") do
1
end
end
我希望这会将一个名为 bar
的 class 方法添加到 Foo
,但是当我调用该方法时它说它未定义。更让我困惑的是,当我使用 def
而不是 define_method
时,相同的代码仍然有效。当我也尝试使用 class_eval
定义实例方法时,这两种方法似乎都有效。那么这里到底发生了什么?
提前致谢。
这是一个实例方法。所以:
f = Foo.new
f.bar # 1
让我们简单点。
define_method
是一种方法。或者我应该说对象 class 的私有 class 方法。您可以通过给它一个参数作为您要定义的实例方法名称和一个包含该方法代码的块来调用它。 apidock定义非常明确。您可能需要阅读文档。
def
是关键字。您可以像往常一样使用它来定义方法。与元编程没有太大关系。
如果您尝试定义 class 方法,请使用 class_eval,并给它一个字符串。顾名思义,instance_eval
在实例级别定义内容。在您的代码中,如果您执行 Foo.instance_methods
,您将找到 bar
方法。因此,如果您 Foo.new.bar
它 returns 1
,正如 TK-421 回答您的那样。但是由于 define_method
定义了 instance_method,如文档所示,无论您使用 class_eval 还是 instance_eval,您都将获得实例方法。
这是您可以阅读的文档,它们会回答您的所有问题。
class_eval: http://apidock.com/ruby/v1_9_3_392/Module/class_eval
define_method: http://apidock.com/ruby/Module/define_method
instance_eval: http://apidock.com/ruby/Object/instance_eval
别忘了这一切:http://www.google.com :D
def 和 define_method 之间的差异。
1:- define_method 可以使用定义范围内的变量。
local_var = "Hello World"
def greet1
local_var #undefined local_var
end
define_method(:greet2) do
local_var # returns local_var
end
2:- 如果要定义名称存储在变量中的方法,则必须使用 define_method。您不能使用 def.
动态声明方法
因此根据要求,您将不得不使用 def 或 define_method。
代码说明。
在这里您必须使用#define_singleton_method 而不是#define_method 来为 Foo class 定义 class 方法。 define_method 将为 class Foo
定义实例方法
所以预期的代码应该是
class Foo
end
Foo.instance_eval do
define_singleton_method("bar") do
1
end
define_method("baz") do
2
end
end
Foo.bar #=> 1
Foo.new.baz #=> 2
我目前正在学习 ruby 元编程,当我在玩弄和测试东西时,我偶然发现了一些我似乎无法找到答案的东西。假设我们有以下代码:
class Foo
end
Foo.instance_eval do
define_method("bar") do
1
end
end
我希望这会将一个名为 bar
的 class 方法添加到 Foo
,但是当我调用该方法时它说它未定义。更让我困惑的是,当我使用 def
而不是 define_method
时,相同的代码仍然有效。当我也尝试使用 class_eval
定义实例方法时,这两种方法似乎都有效。那么这里到底发生了什么?
提前致谢。
这是一个实例方法。所以:
f = Foo.new
f.bar # 1
让我们简单点。
define_method
是一种方法。或者我应该说对象 class 的私有 class 方法。您可以通过给它一个参数作为您要定义的实例方法名称和一个包含该方法代码的块来调用它。 apidock定义非常明确。您可能需要阅读文档。
def
是关键字。您可以像往常一样使用它来定义方法。与元编程没有太大关系。
如果您尝试定义 class 方法,请使用 class_eval,并给它一个字符串。顾名思义,instance_eval
在实例级别定义内容。在您的代码中,如果您执行 Foo.instance_methods
,您将找到 bar
方法。因此,如果您 Foo.new.bar
它 returns 1
,正如 TK-421 回答您的那样。但是由于 define_method
定义了 instance_method,如文档所示,无论您使用 class_eval 还是 instance_eval,您都将获得实例方法。
这是您可以阅读的文档,它们会回答您的所有问题。
class_eval: http://apidock.com/ruby/v1_9_3_392/Module/class_eval
define_method: http://apidock.com/ruby/Module/define_method
instance_eval: http://apidock.com/ruby/Object/instance_eval
别忘了这一切:http://www.google.com :D
def 和 define_method 之间的差异。
1:- define_method 可以使用定义范围内的变量。
local_var = "Hello World"
def greet1
local_var #undefined local_var
end
define_method(:greet2) do
local_var # returns local_var
end
2:- 如果要定义名称存储在变量中的方法,则必须使用 define_method。您不能使用 def.
动态声明方法因此根据要求,您将不得不使用 def 或 define_method。
代码说明。
在这里您必须使用#define_singleton_method 而不是#define_method 来为 Foo class 定义 class 方法。 define_method 将为 class Foo
定义实例方法所以预期的代码应该是
class Foo
end
Foo.instance_eval do
define_singleton_method("bar") do
1
end
define_method("baz") do
2
end
end
Foo.bar #=> 1
Foo.new.baz #=> 2