4

define_method是一种方法Module

在 Ruby 2.0 中,define_method可以在顶层使用;它不必在类或模块中。

define_method :kick do
  puts "method"
end

在 Ruby 1.9 中,main对象没有方法define_method

define_method :kick
# => NoMethodError: undefined method `define_method' for main:Object

Ruby 2.0 如何实现这一点?

4

2 回答 2

2

我也对这个功能很好奇,用irb试了一下。请看一下:

% irb
2.0.0-p353 :001 > method(:define_method)
=> #<Method: main.define_method> 
2.0.0-p353 :002 > private_methods(false)
=> [:public, :private, :include, :using, :define_method, :irb_exit_org, :default_src_encoding, :irb_binding] 
2.0.0-p353 :003 > singleton_class.private_instance_methods(false)
=> [:public, :private, :include, :using, :define_method, :irb_exit_org] 

它表明define_method是主对象(顶层self)的私有单例方法。

于 2014-02-04T01:47:44.553 回答
0

基于 uncutstone 的侦查,define_method() 不会被 main 的单例类继承:

class <<self
  p private_instance_methods(false)
end

--output:--
[:public, :private, :include, :using, :define_method]

...据我所知,如果一个方法没有被继承,它必须在类中定义。请注意,当您包含一个模块时,ruby 会创建一个匿名类并将模块的 defs 插入匿名类中,然后将匿名类直接插入方法查找链中包含类的上方,例如:

module A
  def greet
    puts 'hi'
  end
end

class Dog
  include A
end

p Dog.instance_methods(false)
p Dog.instance_methods.grep(/^g/)

--output:--
[]
[:greet]

输出显示 greet() 是一个继承方法。但是因为define_method() 没有被main 的单例类继承,所以define_method() 不能通过包含模块来获取。相反,define_method() 似乎必须在 main 的单例类中定义。因此,实现它的一种方法是让 ruby​​ 解释器在解析代码之前执行以下代码:

class <<self
  def define_method(x, *y)
    #same code as in Module's define method
  end
end
于 2014-06-26T02:00:37.267 回答