2011-09-19 39 views
4

是否有可能不分配上下文到lambda?Ruby将上下文分配给lambda?

例如:

class Rule 
    def get_rule 
    return lambda {puts name} 
    end 
end 

class Person 
    attr_accessor :name 

    def init_rule 
    @name = "ruby" 
    Rule.new.get_rule.call() # should say "ruby" but say what object of class Rull, does not have variable name 
    # or self.instance_eval &Rule.new.get_rule 
    end 
end 

我的目标是 - >存储过程的对象没有上下文,并在特定的地方调用之前分配上下文。可能吗?

+0

仅供参考; [这是一个愚蠢](http://stackoverflow.com/questions/3133969/ruby-lambda-context),并搜索谷歌的“红宝石绑定上下文到lambda”提供该链接加上其他人。 –

回答

7

是的,但要小心,这个很容易被滥用。我个人会对这样的代码感到担忧。

class Rule 
    def get_rule 
    Proc.new { puts name } 
    end 
end 

class Person 
    attr_accessor :name 

    def init_rule 
    @name = "ruby" 
    instance_eval(&Rule.new.get_rule) 
    end 
end 
6

派对迟了一点,但这是通过显式传递上下文到规则来做到这一点的替代方法。

class Rule 
    def get_rule 
    return lambda{|context| puts context.name} 
    end 
end 

class Person 
    attr_accessor :name 
    def init_rule 
    @name = "ruby" 
    Rule.new.get_rule.call(self) 
    end 
end 

Person.new.init_rule 
#=> ruby 
+1

绝对好得多,但这里不需要lambda,这只是一种方法。不过,我仍然对这种依赖关系的代码感到担忧。当规则调用使人变异的方法时,问题就出现了,现在,如果不理解规则所做的一切,你就无法理解人如何变化。当规则在随机类/文件中被临时定义时,它会变得更糟,你不能只是阅读代码才能知道。传递obj是正确的,但规则应尽可能形式化,而Person不应该是决定调用它的人(推送给调用者)。 –

0

在被真的迟到了;-)

的精神,我认为你正在使用这里的模式是策略模式。 这就分隔了改变“规则”的代码和被重用的“人”部分之间的关​​系。这种模式的另一个优点是 ,您可以在运行时更改规则。

,怎么会看

class Person 
    attr_accessor :name 

    def initialize(&rules) 
    @name = "ruby" 
    instance_eval(&rules) 
    end 
end 

Person.new do 
    puts @name 
end 

=> ruby 
+0

传递规则更好,但是它在初始化时发生,没有必要,并且仍然受到实例评估的影响。 –