2016-05-06 12 views

答えて

9

あなたはinstance_evalを使用する必要があります。

a.instance_eval { @var_one = 1 } 
=> 1 
a.instance_variables 
=> [:@var_one] 

あなたはIRBでそれを行う場合は、通常のevalを使用する場合は、あなたが現在selfの文脈の中で、あなたのインスタンス変数を定義し、それがmainオブジェクトです:

a.eval { self } 
=> main 

したがって、a.evalのメソッドを変更するには、インスタンスのコンテキストでブロックを実行します。

def a.eval(&block) 
    instance_eval &block 
end 

a.eval { @a = 1 } 
=> 1 
a.instance_variables 
=> [:@a] 
2

あなたの目標は、プログラムのインスタンス変数を設定している場合は、あなたが使用することができます。

a.instance_variable_set(:@var_one, 1) 
0

あなたがevalinstance evalの違いを知っている必要があります。

Kernel.evalは、現在の文字列を評価コンテキストまたは指定されたバインディングのコンテキストIRBが入力を処理するために使用する方法です。現在のコンテキストの新しい変数とメソッドを定義することができます。

Object.instance_evalは、特定のクラスインスタンスのコンテキスト内で文字列(または指定されたブロック)を評価し、attrまたはattr_accessorのないクラスプロパティに直接アクセスできるようにします。インスタンスの新しいメソッドを定義することができます。

ので:

a.instance_eval { @var_one = 1 } 
a.instance_variables 
# => [:@var_one] 
+1

@mhaseevはとても 'Kernel.eval'を使用していない、彼自身の' eval'を定義しました。答えは、ブロックのバインディングと直接関係し、 'yield'や 'Proc#call'がそのバインディングとどのようにやりとりするのかと思います。 –