2

クラスの instance_eval ブロッ​​ク内でメソッドを定義すると、問題のないクラス メソッドが作成されます。

例えば)

class A
end

A.instance_eval do
  def method; end
end

A.method #works

しかし、instance_eval 内で define_method を使用すると、クラス メソッドの代わりにインスタンス メソッドが作成されます。

A.instance_eval do
  define_method(:method1) {}
end
A.method1 # NoMethodError: undefined method `method1'
A.new.method1 # Works fine

上記の現象が理解できません。誰か助けてください。

4

3 に答える 3

0

為に:

class A; end

A.instance_eval do
  puts "self=#{self}"
  def m; puts "hi"; end
  define_method(:n) {puts "ho" }
end
  #=> "self=A"

次のことがわかります。

A.methods(false)          #=> [:m] 
A.instance_methods(false) #=> [:n] 
A.m                       # hi
A.n                       # NoMethodError:...
A.new.m                   # NoMethodError:...
A.new.n                   # ho

A.instance_evalはクラスを開きA、メソッドmは で定義されAます。次に、define_methodメソッドが呼び出され、:nレシーバーにインスタンス メソッドが作成されますA

BasicObject#instance_evalではなくModule#class_evalを使用するとします。

A.class_eval do
  puts "self=#{self}"
  def m; puts "hi"; end
  define_method(:n) {puts "ho" }
end
  #=> "self=A"

次のことがわかります。

A.methods(false)          #=> [] 
A.instance_methods(false) #=> [:m, :n] 
A.m                       # NoMethodError:...
A.n                       # NoMethodError:...
A.new.m                   # hi
A.new.n                   # ho

したがって、この動作は次と同じであることがわかります。

class A
  puts "self=#{self}"
  def m; puts "hi"; end
  define_method(:n) {puts "ho" }
end

defここで、インスタンス メソッドは または のいずれかで定義できますdefine_method

于 2015-06-23T22:01:22.700 に答える