2
class Temp1
  def add(s)
    match = 'test'
    self.class.class_eval do
       define_method(s) do
         puts match
       end
    end
    #match ='haha'
  end
end

考えてみると、「match」はローカル変数なので、別のメソッドからどのように表示されるのかわかりません。また、#match =「haha」のコメントを外すと、メソッドは「haha」を何らかの方法で出力します。誰かがそれを説明できますか?

また、ここでは class_eval または instance_eval の使用に違いは見られませんが、同じことをしているようです。

最後になりましたが、ここで define_method を使用してクラス メソッドを作成できますか? Temp1.new.something ではなく、Temp1.something のように呼び出すことができますか?

4

1 に答える 1

5

ブロック (do...end) はクロージャーであり、周囲のスコープにアクセスできるためです。

でブロックを使用しclass_evalたため、メソッドのスコープである周囲にアクセスできますadddefine_methodここで、別のブロックを で使用します。addこのブロックは、class_eval. matchメソッドのスコープ内にローカル変数が作成されましたadd。したがって、ブロックは変数にアクセスできます。

最後になりましたが、ここで define_method を使用してクラス メソッドを作成できますか?

いいえ、できません。レシーバーでインスタンス メソッドを定義します。です。の下で、メソッドを使用して、クラスのインスタンス メソッドを定義しています。祖先チェーン クラスが存在するすべてのクラスのプライベート クラス メソッドです。define_method self.classTemp1Temp1.class_eval do..endTemp1define_methoddefine_methodObject

class C;end
C.private_methods.grep(/define_/)
# => [:define_method]

また、ここではclass_evalまたはinstance_evalの使用に違いは見られません。同じことをしているようです。

わかった!説明させてください。と のインスタンスのように、ここでTeamp1は違いを確認できません。callとの両方で、文書化されているそれぞれの定義により、がに設定されています。ClassClassclass_evalinstance_evalselfTeamp1

class C
  def self.bar;11;end
  def baz;12;end
end

C.is_a? Class # => true
C.instance_of? Class # => true

C.class_eval{ bar } # => 11
C.instance_eval{ bar } # => 11

お役に立てれば!

于 2013-11-02T14:52:39.443 に答える