У меня есть пара модулей, расширяющих метод, отсутствует:
module SaysHello
def respond_to?(method)
super.respond_to?(method) || !!(method.to_s =~ /^hello/)
end
def method_missing(method, *args, &block)
if (method.to_s =~ /^hello/)
puts "Hello, #{method}"
else
super.method_missing(method, *args, &block)
end
end
end
module SaysGoodbye
def respond_to?(method)
super.respond_to?(method) || !!(method.to_s =~ /^goodbye/)
end
def method_missing(method, *args, &block)
if (method.to_s =~ /^goodbye/)
puts "Goodbye, #{method}"
else
super.method_missing(method, *args, &block)
end
end
end
class ObjectA
include SaysHello
end
class ObjectB
include SaysGoodbye
end
Все это работает хорошо, например ObjectA.new. hello_there
выводит «Hello, hello_there»
. Аналогично, ObjectB.new.goodbye_xxx
выводит «Goodbye, xxx»
. response_to?
] также работает, например ObjectA.new.respond_to?: hello_there
return true.
Однако это не очень хорошо работает, если вы хотите использовать оба SaysHello
и ] SaysGoodbye
:
class ObjectC
include SaysHello
include SaysGoodbye
end
Хотя ObjectC.new.goodbye_aaa
работает правильно, ObjectC.new.hello_a
ведет себя странно:
> ObjectC.new.hello_aaa
Hello, hello_aaa
NoMethodError: private method `method_missing' called for nil:NilClass
from test.rb:22:in `method_missing' (line 22 was the super.method_missing line in the SaysGoodbye module)
Он выводит правильно, а затем выдает ошибку. Также response_to?
неправильно, ObjectC.new.respond_to? : hello_a
возвращает false.
Наконец, добавление этого класса:
class ObjectD
include SaysHello
include SaysGoodbye
def respond_to?(method)
super.respond_to?(method) || !!(method.to_s =~ /^lol/)
end
def method_missing(method, *args, &block)
if (method.to_s =~ /^lol/)
puts "Haha, #{method}"
else
super.method_missing(method, *args, &block)
end
end
end
Тоже странно. ObjectD.new.lol_zzz
работает, однако ObjectD.new.hello_a и ObjectD.new.goodbye_t
генерируют исключение имени после вывода правильной строки. response_to?
также не работает для методов hello и goodbye.
Есть ли способ заставить все это работать правильно? Также было бы полезно объяснить, как взаимодействуют method_missing
, Modules и super
.
РЕДАКТИРОВАТЬ: Coreyward решил проблему, если я использую super вместо super.
во всех определяемых мной методах, программа работает правильно. Я не понимаю, почему это так, поэтому я задал еще один вопрос по этому поводу на Что super.