instance_variables
メソッドがa
という変数に対して@var_one
を表示しないのはなぜですか?シングルトンクラスとインスタンス変数
a = Object.new
def a.my_eval; yield end
a.my_eval { @var_one = 1 }
a.instance_variables
# => []
instance_variables
# => [@var_one]
instance_variables
メソッドがa
という変数に対して@var_one
を表示しないのはなぜですか?シングルトンクラスとインスタンス変数
a = Object.new
def a.my_eval; yield end
a.my_eval { @var_one = 1 }
a.instance_variables
# => []
instance_variables
# => [@var_one]
あなたは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]
あなたの目標は、プログラムのインスタンス変数を設定している場合は、あなたが使用することができます。
a.instance_variable_set(:@var_one, 1)
あなたがeval
とinstance eval
の違いを知っている必要があります。
Kernel.eval
は、現在の文字列を評価コンテキストまたは指定されたバインディングのコンテキストIRBが入力を処理するために使用する方法です。現在のコンテキストの新しい変数とメソッドを定義することができます。
Object.instance_eval
は、特定のクラスインスタンスのコンテキスト内で文字列(または指定されたブロック)を評価し、attr
またはattr_accessor
のないクラスプロパティに直接アクセスできるようにします。インスタンスの新しいメソッドを定義することができます。
ので:
a.instance_eval { @var_one = 1 }
a.instance_variables
# => [:@var_one]
@mhaseevはとても 'Kernel.eval'を使用していない、彼自身の' eval'を定義しました。答えは、ブロックのバインディングと直接関係し、 'yield'や 'Proc#call'がそのバインディングとどのようにやりとりするのかと思います。 –