Существуют “пары” методов:

  • #to_i + #to_int
  • #to_s + #to_str
  • #to_a + #to_ary
  • etc.

Только сегодня узнал разницу между ними. В книге “The Ruby Programming Language” более “длинные” версии методов называются “implicit conversion methods”. И реализованы они, как выяснилось, не у всех классов (раньше я думал, что это просто ненужные алиасы для тех, кто пришел из других языков).

Собственно, наличие, например, метода #to_int означает, что данный объект в любом контексте можно интерпретировать, как целое число. Например, у класса String этого метода нет (внезапно). Действительно, хоть и у любой строки можно вызвать метод #to_i, это вовсе не означает, что любую строку можно интерпретировать, как целое число, 'например, эту нельзя, ведь здесь даже нет цифр!'.

Пример

Сходу:

class Dog
  attr_reader :name

  def initialize(name)
    @name = name.to_s
  end

  def to_str
    name
  end
end

lucky = Dog.new('Lucky')
puts 'I have dog. It\'s name is ' + lucky

Пример весьма скучный. Особенно, учитывая то, что, скорее всего, вы написали бы puts "I have dog. It's name is #{lucky}", а это бы не сработало, т.к. при интерполяции вызывается именно явное приведение #to_s.

Так зачем же?

Лично я не могу придумать ситуации, когда неявное приведение может действительно пригодиться. Причем, “неявность” достаточно условная, потому что она проявляется только в том, что некоторые библиотечные методы ее используют (например, строковый метод +).

Я считаю, что лучше использовать явное приведение, это намного понятнее и прозрачнее. Хотя, конечно, знания лишними не бывают.

lucky = Dog.new('Lucky')
guffy = Dog.new('Guffy')

puts "Dog list:", [lucky, guffy].join("\n")

# instead of
puts "Dog list:", [lucky, guffy].map(&:name).join("\n")