Я изучаю метапрограммирование в Ruby и просто пробую определять отсутствующие методы через method_missing и define_method. Я получаю некоторое неожиданное поведение и хотел бы узнать, может ли кто-нибудь объяснить это. Вот мой класс:
class X
def method_missing(m, *args, &block)
puts "method #{m} not found. Defining it."
self.class.send :define_method, m do
puts "hi from method #{m}"
end
puts "defined method #{m}"
end
end
Теперь, этот код:
x = X.new
x.some_method
puts
x.some_method
puts
puts x
Выдает результат:
method some_method not found. Defining it.
defined method some_method
hi from method some_method
method to_ary not found. Defining it.
defined method to_ary
#
Чего я не понимаю, так это последней части: почему Ruby вызывает to_ary в вызове puts? Почему Ruby пытается преобразовать мой объект в массив только для того, чтобы вывести его?
Я погуглил и нашел вот эти ссылки:
Здесь также говорится о проблемах method_missing и to_ary, но не конкретно о том, почему puts может вызвать to_ary.
Я также должен отметить, что поведение не меняется, когда я определяю to_s, например,
def to_s
"I'm an instance of X"
end
Вывод "puts x" выглядит так:
method to_ary not found. Defining it.
defined method to_ary
I'm an instance of X