2013-12-10 52 views
0

在我開始之前,我嘗試過使用instance_eval和singleton方法無濟於事。我將在這個問題上提出我的「最佳」嘗試。紅寶石:正確使用Lambdas

我努力做到以下幾點:

value = rule(condition: lambda {@something > 100}) 
value.act(120) 

以上調用不能改變。

什麼可以改變的規則是如何定義的:

def rule(condition: nil) 
    t = Object.new 
    t.class.module_eval{ 
     attr_accessor :condition  

     def act(something) 
      if(condition.call(something)) 
       return "SUCCESS" 
      end 
     end 
    } 
    t.condition = condition 
    return t 
end 

我不確定如何獲取拉姆達代碼塊得到的東西的價值。任何幫助或點在正確的方向將不勝感激!

+0

這與您的確切問題無關,但我會建議製作一個Rule規則類而不是單一對象工廠方法,除非您有充分理由不這樣做。 – Linuxios

+0

您是否在說您不想更改示例lambda定義的方式?最簡單的解決方案包括將lambda更改爲接受參數(至今爲止的答案)。 – Max

+0

@Max - 確切地說 - 我不想改變示例lambda的定義 –

回答

3

如果這些調用不能改變:

value = rule(condition: lambda {@something > 100}) 
value.act(120) 

嘗試instance_exec

def rule(condition: nil) 
    t = Object.new 
    t.class.module_eval do 
    attr_accessor :condition  

    def act(something) 
     @something = something 

     if(instance_exec &condition) 
     "SUCCESS" 
     else 
     "FAILURE" 
     end 
    end 
    end 
    t.condition = condition 
    t 
end 

它會調用t的背景條件。

+0

Exactlty我在找什麼,**謝謝**! –

0

你正在定義rule對,你只是定義你的條件lambda錯誤。嘗試使用此代替:

value = rule(condition: lambda {|arg| arg > 100}) 

這告訴Ruby,lambda需要一個參數。你已經在你的rule函數中傳遞了參數。

如果你需要保持你的語法規則一樣,(我反對這項建議),你可以定義改成這樣:

def rule(condition: nil) 
    t = Object.new 
    t.class.module_eval{ 
     attr_accessor :condition  

     def act(something) 
      argobj = Object.new 
      argobj.instance_variable_set(:something, something) 
      if(argobj.instance_eval(&(condition()))) 
       return "SUCCESS" 
      end 
     end 
    } 
    t.condition = condition 
    return t 
end 
+0

感謝您的迴應!有什麼辦法讓規則調用保持不變('value = rule(condition:lambda {@something> 100})')並且只更改規則的定義? –

+0

總之,我不想改變如何定義lambda –

+0

@ user3019655:請參閱編輯。 – Linuxios

0

你接近,你的拉姆達需要採取的參數。

def rule(condition: nil) 
    t = Object.new 
    t.class.module_eval do 
    attr_accessor :condition  

    def act(something) 
     if(condition.call(something)) 
     "SUCCESS" 
     else 
     "FAILURE" 
     end 
    end 
    end 
    t.condition = condition 
    t 
end 

derp = rule(condition: lambda { |val| val > 100 }) 
puts derp.act(120) 
puts derp.act(80) 

甚至更​​好,得到stabby!

derp = rule(condition: ->(val) { val > 100 }) 
+0

感謝您的迴應!有什麼辦法讓規則調用保持不變('value = rule(condition:lambda {@something> 100})')並且只更改規則的定義? –

+0

總之,我不想改變lambda的定義 –