Ruby instance_eval
Posted: July 2nd, 2011 | Author: Andrea | Filed under: ruby | Tags: ruby | No Comments »Working on one of my first ruby gem I have started to learn more about ruby meta programming and ruby core language.
My gem needs a sort of singleton class that needs to be configured when the application starts. I have choosed to use a Module as singleton cause a ruby module cannot be initialized and so it just fits my needs.
I will then include the configured module into the model that will need it.
What I wanted to achieve was something like:
include My_package;
My_module.configure do set :my_setting, :my_value set :another_setting, :another_valueendI created my module and added 2 class methods one called configure that is planned to take care of the block and a method called set that is going to apply the requested configurations.
Something like this:
module Andrea module My_module def self.configure yield end def self.set(arg) puts arg end end end
#anywhere in my program initilizersinclude Andrea
My_module.configure do set "my setting"end If you run this code you get an exception saying to you that:
undefined method ‘set’ for main:Object
This was a bit confusing at first. The error is thrown cause the block is created outside of the module scope and is executed in the scope where it was created. In this special case the scope is the general Object scope.
What I need is that the block passed to the configure method is executed in the scope of My_module. This can be achieved using the instance_eval method.
Passing the block as argument to instance_eval this is executed in the current self scope. Exactly what I need.
module Andrea module My_module def self.configure &block instance_eval &block end def self.set(arg) puts arg end end end
In conclusion instance_eval is one of the important topic in ruby meta programming allowing blocks to be sent around and executed in the calling instance scope.




Leave a Reply