2011-09-19 49 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

傳遞規則更好,但是它在初始化時發生,沒有必要,並且仍然受到實例評估的影響。 –