2013-12-10 25 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的定义 –