次のコードは失敗します
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
は「すべての意図と目的のために、私は文字列です」という意味です。
シンボルはnot文字列であるため、明示的な変換なしでは連結できません。これを試して:
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"