Ответ 1
puts
является синонимом $stdout.puts
. $stdout - это класс IO
, поэтому посмотрите документацию IO.puts:
Записывает данные объекты в ios, как с печатью ввода-вывода #. Записывает запись разделитель (обычно это новая строка) после того, что еще не заканчивается последовательность новой строки. Если вызывается с аргументом массива, записывается каждый элемент на новой строке.
Это означает, что метод puts
предназначен для записи нескольких строк вывода. Таким образом, он пытается вызвать метод to_ary
для объекта и если to_ary
определен, то печатает каждый элемент возвращенного Array
в новой строке, иначе puts
вызывает метод to_s
.
to_ary
внутреннее использование в документах Ruby действительно недостаточно хорошо документировано (Matz указывает на это в книге "Язык программирования Ruby" ).
Методы print
и p
, с другой стороны, не вызывают to_ary
, только to_s
.
Sidenote: Интересно, что to_ary
должен возвращать реальный объект Array
, а не объект, определяющий метод each
или что-то еще:
class Test
def to_ary
10.downto(1)
end
end
puts Test.new
#TypeError: can't convert Test to Array (Test#to_ary gives Enumerator)
# from (irb):28:in `puts'
# from (irb):28:in `puts'
# from (irb):28