Изменение привязки 'Proc' во время вызова

Действительно ли возможно изменить привязку процедуры в течение времени вызова?

class AllValidator
  def age_validator
    Proc.new {|value| self.age > value }
  end
end

class Bar
  attr_accessor :age
  def doSomething
    validator = AllValidator.new.age_validator
    validator.call(25) # How to pass self as the binding?
  end
end

В коде выше, как я изменяю привязку proc во время вызова? Есть ли способ передать привязку во многом как eval функция?

Отметьте, Был ли пример выше реален, я использовал бы mixin/inheritence и т.д. Я использую код для демонстрации моего проблемного сценария.

7
задан Harish Shetty 30 August 2011 в 17:52
поделиться

1 ответ

Вы можете использовать instance_eval :

class Bar
  def do_something
    validator = AllValidator.new.age_validator

    # Evaluate validator in the context of self.
    instance_eval &validator
  end
end

Если вы хотите передавать аргументы (как указано в комментарии ниже), вы можете использовать instance_exec вместо instance_eval , если вы используете Ruby 1.9 или Ruby 1.8.7:

class Bar
  def do_something
    validator = AllValidator.new.age_validator

    # instance_exec is like instance_eval with arguments.
    instance_exec 5, &validator
  end
end

Если вам нужно заставить его работать с Ruby 1.8.6 и ниже, ваш лучший выбор - связать процедуру как метод Bar :

class Bar
  def do_something
    self.class.send :define_method, :validate, &AllValidator.new.age_validator
    self.validate 5
  end
end

Альтернативой является реализация instance_exec более старых версий Ruby ( пример здесь ). Все, что он делает, это определяет метод перед его вызовом и отменяет его определение после того, как вы закончите.

12
ответ дан 6 December 2019 в 21:12
поделиться
Другие вопросы по тегам:

Похожие вопросы: