Действительно ли возможно изменить привязку процедуры в течение времени вызова?
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
и т.д. Я использую код для демонстрации моего проблемного сценария.
Вы можете использовать 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 ( пример здесь ). Все, что он делает, это определяет метод перед его вызовом и отменяет его определение после того, как вы закончите.