2013-12-10 3 views
0

Прежде чем я начну, я попытался использовать методы instance_eval и singleton безрезультатно. Я собираюсь представить свою «лучшую» попытку решить эту проблему.Ruby: Правильно использовать 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» вместо метода фабрики Singleton, если у вас нет веской причины. – Linuxios

+0

Вы говорите, что не хотите изменять способ определения лямбда? Самое простое решение включает в себя изменение лямбда, чтобы принять аргумент (как до сих пор дают ответы). – Max

+0

@Max - точно - я не хочу изменять способ определения лямбда –

ответ

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 «s.

+0

Точно, что я ищу, ** спасибо ** !!! –

0

Вы определяете rule правильно, вы просто определяете свое состояние лямбда неправильно. Попробуйте использовать это вместо:

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

Это говорит Руби, что лямбда принимает один аргумент. Вы уже передаете аргумент в своей функции 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

Короче говоря, я не хочу изменять способ определения лямбда –

+0

@ user3019655: См. Edit. – 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) 

Или даже лучше, получите прочный!

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

Спасибо за ответ! Есть ли способ, чтобы вызов правила оставался таким же ('value = rule (condition: lambda {@something> 100})') и ТОЛЬКО изменил определение правила? –

+0

Короче говоря, я не хочу менять способ определения лямбда –