2013-08-04 12 views
5

私はsendが引数付きの文字列またはシンボルを受け取るのに対して、instance_evalは文字列またはブロックをとり、その差は受信側が明らかになる可能性があることを知っています。sendとinstance_evalのRubyの違いは?

私の質問は「」の相違点は以下の例のようになりますか?私の質問は「フード」ですか? fine manualから

1234.send 'to_s'    # '1234' 
1234.instance_eval 'to_s'  # '1234' 

答えて

7

送信(シンボル[、引数...])→OBJ
送信(文字列[、引数...])→OBJ

シンボルで識別されるメソッドを呼び出し、指定された引数を渡します。 [...]メソッドが文字列で識別されると、文字列はシンボルに変換されます。

instance_eval用:

instance_evalを(文字列[、ファイル名[、LINENO]])→OBJ
instance_evalを{| |ブロック}→obj

受信者のコンテキスト内でRubyソースコードまたは指定されたブロックを含む文字列を評価します(obj)。コンテキストを設定するために、変数selfは、コードが実行されている間にobjに設定され、objのインスタンス変数へのコードアクセスを与えます。

instance_evalはあなたが上instance_evalを呼び出しているオブジェクトへself設定して(文字列やブロックなど)のコードの任意のブロックを実行し、一方、そうsendは、メソッドを実行します。

instance_evalに渡している文字列が単なる1つの方法であるため、あなたのケースでは、それほど大きな違いはありません。主な違いは、あなたのコードを読んでいる人(6ヶ月であなたを含む)は、なぜinstance_evalを使って単一のメソッドを呼び出すのだろうと思っていることです。また、あなたはsendで行うことができますどのようなObject#public_sendBasicObject#__send__

+1

私は 'instance_eval'のために1つの方法があるのはなぜかと思います。 –

5

に興味があるかもしれません

instance_evalのそれの適切なサブセットです。つまり、sendへの引数は単一のメソッド(とその引数)でなければならないが、instance_methodへの引数は任意のコードである。したがって、sendがある場合はいつでも、instance_evalで書き換えることができますが、その逆はできません。

しかし、instance_evalニーズが全体の引数を解析するのに対し、sendを実行するために必要な追加の解析が存在しないためsendinstance_evalよりもはるかに高速で、performancewise。

例では、結果は同じになりますが、最初のものはより高速に実行されます。

+1

素敵な要約、そしてパフォーマンスについてのボーナスを得ました! –

関連する問題