Изменение привязки `Proc` во время вызова - PullRequest
7 голосов
/ 02 марта 2010

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

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 и т. Д. Я использую код для демонстрации своего проблемного сценария.

1 Ответ

12 голосов
/ 02 марта 2010

Вы можете использовать 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 и ниже, лучше всего связыватьсяproc как метод Bar:

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...