dynamic ruby. lesson #5: define_method and its friends
TRANSCRIPT
DEFINE_METHOD
Существуют два типа objectified methods: объекты класса Method и объекты класса UnboundMethod. Это так называемые “связанные” и “несвязанные” методы-объекты.
BOUND METHODS
“Связанные” методы всегда ассоциированы с каким-то конкретным объектом (receiver-ом).Создаются при помощи вызова метода Object#method.
UNBOUND METHODS
“Несвязанные” методы не привязаны к конкретному объекту (receiver-у).Они создаются при помощи вызова метода Module#instance_method или методом “отвязывания” обычного метода.
UNBOUND METHODS
Unbound methods не могут быть выполнены при помощи метода call. Но они могут быть снова привязаны к некоторому receiver-у при помощи метода UnboundMethod#bind.
UNBOUND METHODS
Объект, к которому мы можем подвязать unbound method должен быть частью дерева наследования оригинального класса, которому принадлежал этот метод.
PROC IN DEFINE_METHOD
Итак, с методами разобрались.Вернемся к блокам.
Если в качестве тела метода, который создается через define_method, мы передадим блок, то в каком контексте он будет выполняться?
PROC IN DEFINE_METHOD
На помощь приходит BasicObject#instance_eval.
Этот метод выполняет “evaluate” строки, содержащей ruby код или блока (но уже в контексте receiver-a).
PROC IN DEFINE_METHOD
Подобную к instance_eval миссию выполняет instance_exec, принимающий только блок, но зато с аргументами.
Кроме того, существует семантически близкая пара методов class_eval и class_exec, расширяющая контекст не объекта, но класса, который объект описывает.
T I P
PROC IN DEFINE_METHOD
Как и при статическом объявлении метода, у вас остается возможность определять аргументы по умолчанию.
Все как и раньше, только аргументы определяются через в соответствии с синтаксисом блока.
DEFINE_METHOD AND ITS FRIENDS
REFERENCES
▸ https://ruby-doc.org/core-2.3.1/Module.html#method-i-define_method
▸ https://ruby-doc.org/core-2.3.1/UnboundMethod.html
▸ http://stackoverflow.com/a/9057977
▸ http://www.saturnflyer.com/blog/jim/2015/04/22/the-difference-between-instance_eval-and-instance_exec/
THANK YOU!
Alex Mikitenko [email protected] https://github.com/nonkor