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 がメイン オブジェクト (最上位の自己) のプライベート シングルトン メソッドであることを示しています。

于 2014-02-04T01:47:44.553 に答える
0

アンカットストーンの調査に基づいて構築された define_method() は、メインのシングルトン クラスに継承されません。

class <<self
  p private_instance_methods(false)
end

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

...そして、私が判断できる限り、メソッドが継承されていない場合は、クラスで定義する必要があります。モジュールをインクルードすると、ruby は匿名クラスを作成し、モジュールの定義を匿名クラスに挿入し、メソッド ルックアップ チェーンのインクルード クラスのすぐ上に匿名クラスを挿入することに注意してください。たとえば、次のようになります。

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 の singleton クラスに継承されていないため、モジュールをインクルードして define_method() を取得することはできません。代わりに、define_method() がメインのシングルトン クラスで定義されている必要があるようです。したがって、これを実装する 1 つの方法は、コードを解析する前に Ruby インタープリターに次のコードを実行させることです。

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