Le code suivant échoue
world = :world
result = 'hello' + world
puts result #=> can't convert Symbol into String
Le code suivant fonctionne
world = :world
result = "hello #{world}"
puts result #=> hello world
Pourquoi?
Utilisation de Ruby 1.8.7
L'interpolation de chaînes est un appel implicite to_s
. Donc, quelque chose comme ça:
result = "hello #{expr}"
est plus ou moins équivalent à ceci:
result = "hello " + expr.to_s
Comme l'a dit karim79, un symbole n'est pas une chaîne mais les symboles ont des méthodes to_s
Donc votre interpolation fonctionne; votre tentative d'utilisation de +
pour la concaténation ne fonctionne pas car il n'y a pas d'implémentation de +
disponible qui comprend une chaîne à gauche et un symbole à droite.
Le même comportement se produirait si world
était un nombre.
"hello" + 1 # Doesn't work in Ruby
"hello #{1}" # Works in Ruby
Si vous souhaitez ajouter une chaîne à quelque chose, implémentez to_str
dessus:
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
signifie "Vous pouvez me transformer en chaîne", tandis que to_str
signifie "À toutes fins utiles, je suis une chaîne".
Un symbole est pas une chaîne, et en tant que tel, il ne peut pas être concaténé en un sans conversion explicite. Essaye ça:
result = 'hello ' + world.to_s
puts result
En remarque, vous pouvez toujours définir la méthode vous-même :)
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"