Ruby ProC: призывающий метод от класса A из в классе B и использование метода класса B '
-
28-09-2019 - |
Вопрос
Я не уверен, действительно ли это возможно, но я не смог найти четкий ответ в любом месте. Также мне трудно определить мой вопрос в простых «поисках». Поэтому мне жаль, если это уже ответило где-то еще, я не мог его найти.
То, что я хотел бы знать, это если можно создать proc, который содержит метод, который не определен в месте, где определяется proc. Тогда я хотел бы поставить этот экземпляр в другой класс, который имеет метод, и запускает этот метод с прилагаемыми аргументами.
Вот образец того, что я хочу достичь, но не знаю, как.
class MyClassA
# This class does not have the #run method
# but I want Class B to run the #run method that
# I invoke from within the Proc within this initializer
def initialize
Proc.new { run 'something great' }
end
end
class MyClassB
def initialize(my_class_a_object)
my_class_a_object.call
end
# This is the #run method I want to invoke
def run(message)
puts message
end
end
# This is what I execute
my_class_a_object = MyClassA.new
MyClassB.new(my_class_a_object)
Производится следующая ошибка
NoMethodError: undefined method for #<MyClassA:0x10017d878>
И я думаю, что понимаю, почему, это потому, что он пытается вызвать run
Метод на MyClassA
экземпляр, а не тот в MyClassB
. Отказ Тем не менее, есть ли способ, которым я мог сделать run
Призыв команды MyClassB
С. run
Способ экземпляра?
Решение
Есть две проблемы с вашим кодом:
MyClassA.new
не возвращает стоимостьinitialize
Это всегда возвращает экземплярMyClassA
.Вы не можете просто позвонить в ProC, вы должны использовать
instance_eval
метод запуска его в контекстеMyClassB
Вот ваш код исправлен, чтобы работать, как вы хотите:
class MyClassA
def self.get_proc
Proc.new { run 'something great' }
end
end
class MyClassB
def initialize(my_class_a_object)
instance_eval(&my_class_a_object)
end
# This is the #run method I want to invoke
def run(message)
puts message
end
end
# This is what I execute
my_class_a_object = MyClassA.get_proc
MyClassB.new(my_class_a_object) #=> "something great"