【问题标题】:Ruby: difference between def and define_methodRuby:def和define_method之间的区别
【发布时间】:2016-02-24 22:25:03
【问题描述】:

我现在正在学习 ruby​​ 元编程,当我在玩耍和测试东西时,我偶然发现了一些我似乎无法找到答案的东西。假设我们有以下代码:

class Foo
end
Foo.instance_eval do
  define_method("bar") do
    1
  end
end

我希望这会向Foo 添加一个名为bar 的类方法,但是当我调用该方法时,它却说它是未定义的。更让我困惑的是,当我使用def 而不是define_method 时,相同的代码仍然有效。当我尝试使用class_eval 定义实例方法时,这两种方法似乎都有效。那么这里到底发生了什么?

提前致谢。

【问题讨论】:

  • 我在发布我的帖子之前阅读了该帖子,但我不明白。
  • 那道题的题目和这道题几乎一样,但题目不一样。此外,该问题的检查答案过于简洁,无法很好地回答 this 问题。由于这些原因,我认为不应将此问题标记为与该问题重复。

标签: ruby metaprogramming class-method


【解决方案1】:

让我们让它变得简单。

define_method 是一种方法。或者我应该说 Object 类的私有类方法。您通过给它一个参数作为您要定义的实例方法名称和一个包含方法代码的块来调用它。 apidock 有非常明确的定义。您可能需要阅读文档。

def 是一个关键字。您可以使用它来定义方法,就像您一直在做的那样。与元编程无关。

如果您尝试定义类方法,请使用 class_eval,并给它一个字符串。顾名思义,instance_eval 定义了实例级别的东西。在您的代码中,如果您执行Foo.instance_methods,您将找到bar 方法。因此,如果您执行Foo.new.bar,它将返回1,因为 TK-421 回答了您。但是由于define_method定义了instance_method,如文档所示,无论你使用class_eval还是instance_eval,都会得到instance_method。

这是您可以阅读的文档,它们会回答您的所有问题。

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

【讨论】:

  • 非常感谢,确实是一个彻底而清晰的解释:)
【解决方案2】:

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 类定义类方法。 define_method 将为类 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

【讨论】:

    【解决方案3】:

    这是一个实例方法。所以:

    f = Foo.new
    f.bar # 1
    

    【讨论】:

    • 就我而言,这并不能回答defdefine_method 的问题。
    猜你喜欢
    • 1970-01-01
    • 2013-08-12
    • 1970-01-01
    • 2021-12-25
    • 2020-05-10
    • 2014-09-20
    • 2010-10-28
    • 2015-10-04
    • 2012-08-12
    相关资源
    最近更新 更多