Here is updated article on the same topic .
Following code will print
99 as the output.
Nothing great there. However try passing a parameter to
You will get following error.
instance_eval does not allow you to pass parameters to a block.
How to get around to the restriction that instance_eval does not accept parameters
instance_exec was added to ruby 1.9 and it allows you to pass parameters to a proc. This feature has been backported to ruby 1.8.7 so we don’t really need ruby 1.9 to test this feature. Try this.
Above code works. So now we can pass parameters to block. Good.
Changing value of self
Another feature of
instance_exec is that it changes the value of
self. To illustrate that I need to give a longer example.
Notice that in that above case
Developer.lab says “Human”. And that is the right answer from ruby perspective. However that is not what I intended. ruby stores the binding of the proc in the context it was created and hence it rightly reports that self is “Human” even though it is being called by
Go to http://facets.rubyforge.org/apidoc/api/core/index.html and look for
instance_exec method. The doc says
Evaluate the block with the given arguments within the context of this object, so self is set to the method receiver.
It means that
instance_exec evaluates self in a new context. Now try the same code with
In this case
Developer and not
You can also checkout this page which has much more detailed explanation of
instance_exec and also emphasizes that
instance_exec does pass a new value of
instance_exec is so useful that
ActiveSupport needs it. And since ruby 1.8.6 does not have it
ActiveSupport has code to support it.
I came across
instance_exec issue while resolving #4507 rails ticket . The final solution did not need
instance_exec but I learned a bit about it.