1

のドキュメントから次のコードの抜粋を見つけましたinstance_exec

  class KlassWithSecret
    def initialize
      @secret = 99
    end
  end
  k = KlassWithSecret.new
  k.instance_exec(5) {|x| @secret+x }   #=> 104

instance_exec が行う理由についての私の理解は、次の図にあります。シングルトン クラスに @secret + 5 を追加します。

  +-----------------------+
  |   singleton class do  |
  |     def method1       |
  |     ...               |
  |     end               |
  |     ...               |
  |     @secret + 5       |
  |   end                 |
  |                       |
  |                       |
  +-----------+-----------+
              |
    +---------+-------+
    |  instance k     |
    |   @secret       |
    |                 |
    +-----------------+

だから私は同じ結果を得るためにclass_execを使ってコードを思いついた

k.singleton_class.class_exec(5) {|x| @secret + x}

@secret is nil エラーが表示されます。その理由と、私の理解の何が問題なのかを知りたいです

アップデート:

k.instance_exec {binding} と k.singleton_class.class_exec {binding} のバインディング オブジェクトが異なることに気付きました。私はまだ彼らがボンネットの下でどのように機能するか知りたいです

4

1 に答える 1

1

instance_execは C で書かれており、c-api を使用すると、メソッドを実行するときに self の値を指定できます。

ルビーにする前に、適切な人々はシングルトンクラスのコンテキストで何かを実行するだけでなく、シングルトンクラスでメソッドを定義してそれを呼び出すことで実装しました(これはactivesupport 2.xまたはrspec_core'sとして見ることができますinstance_eval_with_args

オブジェクトのシングルトン クラスは、それ自体がオブジェクトであるため、対応するオブジェクトと共有されない独自のインスタンス変数のセットを持ちます。

于 2012-07-02T07:28:27.537 に答える