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.