После отказа кода
world = :world
result = 'hello' + world
puts result #=> can't convert Symbol into String
Работа с кодом работает
world = :world
result = "hello #{world}"
puts result #=> hello world
Почему?
Использование ruby 1.8.7
После отказа кода
world = :world
result = 'hello' + world
puts result #=> can't convert Symbol into String
Работа с кодом работает
world = :world
result = "hello #{world}"
puts result #=> hello world
Почему?
Использование ruby 1.8.7
Интерполяция строк - это неявный вызов to_s
. Итак, что-то вроде этого:
result = "hello #{expr}"
более или менее эквивалентен этому:
result = "hello " + expr.to_s
Как сказал karim79, символ не является строкой, но символы имеют методы to_s
, поэтому ваша интерполяция работает; ваша попытка использования +
для конкатенации не работает, потому что не существует реализации +
, доступной для понимания строки слева и символа справа.
Такое же поведение произойдет, если world
будет числом.
"hello" + 1 # Doesn't work in Ruby
"hello #{1}" # Works in Ruby
Если вы хотите добавить строку к чему-то, внесите в нее to_str
:
irb(main):001:0> o = Object.new
=> #<Object:0x134bae0>
irb(main):002:0> "hello" + o
TypeError: can't convert Object into String
from (irb):2:in `+'
from (irb):2
from C:/Ruby19/bin/irb:12:in `<main>'
irb(main):003:0> def o.to_str() "object" end
=> nil
irb(main):004:0> "hello" + o
=> "helloobject"
to_s
означает "Вы можете превратить меня в строку", а to_str
означает "Для всех целей и целей я являюсь строкой".
Символ не является строкой, и поэтому он не может быть объединен с одним без явного преобразования. Попробуйте следующее:
result = 'hello ' + world.to_s
puts result
В качестве побочного примечания вы всегда можете определить метод самостоятельно:)
ruby-1.9.2-p0 > class Symbol
ruby-1.9.2-p0 ?> def +(arg)
ruby-1.9.2-p0 ?> [to_s, arg].join(" ")
ruby-1.9.2-p0 ?> end
ruby-1.9.2-p0 ?> end
=> nil
ruby-1.9.2-p0 > :hello + "world"
=> "hello world"