/ / Prečo instance_exec a class_exec majú toto odlišné správanie? - rubín, metaprogramovanie

Prečo inštancie_exec a class_exec majú toto odlišné správanie? - rubín, metaprogramovanie

Nasledujúci kód execerpt som našiel z dokumentácie instance_exec

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

Moje chápanie toho, prečo instance_exec robí, je v nasledujúcom diagrame, pridáva @secret + 5 do svojej triedy singleton

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

Takže som prišiel s kódom pomocou class_exec, aby som dosiahol rovnaký výsledok

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

Dáva mi to chybu @secret is nil, chcem vedieť, prečo to je a čo je na mojom porozumení zlé

aktualizácia:

Všimol som si, že k.instance_exec {binding} a k.singleton_class.class_exec {binding} majú rozdielny väzbový objekt, takže musia byť odlišné. Stále chcem vedieť, ako fungujú pod kapotou

odpovede:

1 pre odpoveď č. 1

instance_exec je napísaný v jazyku C a program c-api vám umožňuje určiť, aká je hodnota seba pri vykonávaní metódy.

Predtým, než sa z neho stali správni rubínoví ľudiaimplementoval to tak, že definoval metódu v triede singleton a zavolal ju, nielen vykonaním vecí v kontexte triedy singleton (môžete to vidieť v activesupport 2.x alebo ako rspec_core) instance_eval_with_args)

Trieda singleton objektu je objekt sám o sebe a má teda svoju vlastnú množinu inštančných premenných, ktoré nie sú zdieľané s príslušným objektom.