2010-03-02 47 views
7

是否可以在调用期间更改过程的绑定?在调用期间更改`Proc`绑定

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 

在上面的代码中,如何在调用过程中更改proc的绑定? 有没有办法像eval函数那样传递绑定?

注意 如果上面的例子是真实的,我会用mixin/inheritence等我使用的代码来证明我的问题的方案。

回答

12

您可以使用instance_eval

class Bar 
    def do_something 
    validator = AllValidator.new.age_validator 

    # Evaluate validator in the context of self. 
    instance_eval &validator 
    end 
end 

如果你想传递(如在下面的评论中提到)的参数,你可以使用instance_exec而不是instance_eval,如果你使用Ruby 1.9和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 

如果你必须使它使用Ruby 1.8.6及以下工作为好,最好的办法是给PROC结合为Bar方法:

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

另一种方法是实施instance_exec旧的Ruby版本(example here)。它所做的只是在调用它之前定义一个方法,并在完成后定义它。

+0

这是否允许你将参数传递给'validator'? – 2010-03-02 06:42:30

+0

'instance_eval'有一个姐姐的方法,可以让你做到这一点,见上面的更新。 – molf 2010-03-02 07:11:32

+0

+1感谢您的详细解答。 – 2010-03-02 07:57:13