Foo = Class.new
Foo.class_eval do
def class_bar
"class_bar"
end
end
Foo.instance_eval do
def instance_bar
"instance_bar"
end
end
Foo.class_bar #=> undefined method ‘class_bar’ for Foo:Class
Foo.new.class_bar #=> "class_bar"
Foo.instance_bar #=> "instance_bar"
Foo.new.instance_bar #=> undefined method ‘instance_bar’ for #<Foo:0x7dce8>
メソッドの名前にちょうど基づいてFooにクラスメソッドを追加し、Fooにインスタンスメソッドを追加できるようにinstance_evalを追加できるようにしたいと思います。しかし彼らは反対のことをしているようです。class_eval()とinstance_eval()の違いを理解するにはどうすればよいですか?
上記の例では、Fooクラスでclass_barを呼び出すと未定義のメソッドエラーが発生し、Foo.newから返されたインスタンスでinstance_barを呼び出すと、未定義のメソッドエラーが発生します。両方のエラーは、class_evalとinstance_evalが何をすべきかを直感的に理解することと矛盾しているようです。
実際にこれらの方法の違いは何ですか? class_evalため
ドキュメント:
mod.class_eval(文字列[、ファイル名[、 LINENO]])=>
OBJ MODの 文脈における文字列またはブロックを評価します。これは、クラスにメソッドを追加するために使用することができます 。 instance_evalため
ドキュメント:
{obj.instance_eval | |
OBJブロック} =>は、受信 (OBJ)のコンテキスト内ルビー ソースコード、又は所定のブロック、 を含む文字列を評価します。コンテキストを設定するには、 変数selfがobjに設定され、 コードが実行され、コード にobjのインスタンス変数へのアクセス権が与えられます。
これは素晴らしい説明です。ありがとう。最後の段落まで、私はあなたに続きました。なぜなら、instance_evalがクラスに対して呼び出されたときにクラスメソッドを定義する理由を説明しようとするところです。最後の行は、私がダイジェストするのが特に難しいです。「クラスメソッドを呼び出すのは間違いです。それは、その特定のClassインスタンスのインスタンスメソッドです。」あなたは、すべてのクラスメソッドがそれ以上のものではないということを意味しますか? –
ええ、ちょっと - それはすべてです。私は明日それをもっと明白にしようとします。 – tomafro
素晴らしい - 私はその問題のために特に新しい質問を追加しました: "なぜinstance_eval()はクラスで呼び出されたときにクラスメソッドを定義するのですか?" http://stackoverflow.com/questions/900704/why-does-instanceeval-define-a-class-method-when-called-on-a-class。 –