Changing the `Proc` Binding During a Call

Is it possible to change the binding of a procedure during a call?

class AllValidator def age_validator Proc.new {|value| self.age > value } end end class Bar attr_accessor :age def doSomething validator = AllValidator.new.age_validator validator.call(25) # How to pass self as the binding? end end 

In the above code, how do I change the proc binding during a call? Is there a way to pass the binding in the same way as the eval function?

Note If the above example was real, I would use mixin / inheritence , etc. I am using code to demonstrate my problematic scenario.

+7
ruby ruby-on-rails
source share
1 answer

You can use instance_eval :

 class Bar def do_something validator = AllValidator.new.age_validator # Evaluate validator in the context of self. instance_eval &validator end end 

If you want to pass arguments (as indicated in the comment below), you can use instance_exec instead of instance_eval if you use Ruby 1.9 or Ruby 1.8.7:

 class Bar def do_something validator = AllValidator.new.age_validator # instance_exec is like instance_eval with arguments. instance_exec 5, &validator end end 

If you need to make it work with Ruby 1.8.6 and below, it is best to bind proc as a Bar method:

 class Bar def do_something self.class.send :define_method, :validate, &AllValidator.new.age_validator self.validate 5 end end 

An alternative is to implement instance_exec older versions of Ruby ( example here ). All he does is define the method before calling it and define it after completion.

+12
source share

All Articles