简体   繁体   中英

Understanding Simple `instance_eval` Example

Looking at this instance_eval example:

class KlassWithSecret
    def initialize
        @secret = 99
    end
    def get
        @secret
    end
end
k = KlassWithSecret.new
k.instance_eval { @secret } 
print k.get

I added a get method to KlassWithSecret .

Here's the results of running the program:

>ruby InstanceEvalTest.rb
99

So, does instance_eval here somehow call the initialize method?

I think that I understand this method a bit from reading this helpful post . But I'm still in the dark.

The initialize method is automatically called by Ruby after the new method is called. instance_eval runs the block you supply in the context of the object . This means it has access to anything a normal line of code in the KlassWithSecret class would have.

@secret is an instance variable , meaning that it belongs to an instance of KlassWithSecret . Because we're evaluating { @secret } in the context of a KlassWithSecret instance, we can access @secret .

k.instance_eval gives you access to all of the instance variables (here just @secret ) and all private methods (if there were any). It executes the code in the block, which in this case returns 99 , the value of @secret . Then print k.get prints that value and returns nil .

If the block had been { @secret = 'cat' } , k.instance_val would have changed the value of @secret (and returned the new value).

When using instance_eval , class_eval , class < self and other metaprogramming constructs, you mind find it helpful to track the value of self using puts statements. For example:

k = KlassWithSecret.new #=> #<KlassWithSecret:0x00000101897810 @secret=99>
self #=> main
k.instance_eval { puts "self=#{self}"; @secret }
"self=#<KlassWithSecret:0x00000101897810>"
  #=> 99

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM