【问题标题】:Ruby singleton methods with (class_eval, define_method) vs (instance_eval, define_method)带有(class_eval,define_method)与(instance_eval,define_method)的Ruby单例方法
【发布时间】:2011-03-11 09:26:15
【问题描述】:

Ruby 中的元编程很棒,因为我经常使用它来模拟基于原型的编程,并快速编写一些问题的原型解决方案来测试它们的可行性。所以我想知道以下代码之间是否有任何本质区别:

(class << some_object; self; end).class_eval do
  define_method(:method_name) do ... method body ... end
end

(class << some_object; self; end).instance_eval do
  define_method(:method_name) do ... method body ... end
end

两个版本的代码都定义了单例方法,我还没有遇到任何迫使我选择(instance_eval, define_method) 组合而不是(class_eval, define_method) 组合来定义单例方法的情况,我想知道是否两者有本质区别。

【问题讨论】:

  • 请注意,执行上述操作的最佳方法是define_singleton_method(:method_name) do ... end

标签: ruby metaprogramming


【解决方案1】:

define_method 没有区别。但是当你使用def时会有区别。

o = Object.new  

# class_eval example
class << o; self; end.class_eval { def test1;  :test1; end  }
o.test1 #=> test1

# instance_eval example
class << o; self; end.instance_eval { def test2; :test2; end }
o.test2 #=> NoMethodError

为什么 defdefine_method 之间的行为不同? define_method 是一个方法调用,因此在 eval 上下文中对 self 进行操作。 instance_evalclass_eval 中的 self 是相同的 - 它是接收者(o 的特征类)。

但是def 的行为有所不同,它不是在self 上运行,而是在default define 上运行。对于class_evaldefault defineeself 相同,但对于instance_eval,它是self 的元类。

我们如何访问上面定义的test2 方法? test2 必须是定义在 o 的特征类的元类上的实例方法。

是o的特征类上的类方法:

class << o; test2; end #=> :test2

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-05-23
    • 2012-05-05
    • 1970-01-01
    • 2017-04-22
    • 1970-01-01
    • 1970-01-01
    • 2011-09-27
    相关资源
    最近更新 更多