2011-12-20 15 views
33

Considere el siguiente código:¿Las cadenas en Ruby son mutables?

$ irb 
> s = "asd" 
> s.object_id # prints 2171223360 
> s[0] = ?z  # s is now "zsd" 
> s.object_id # prints 2171223360 (same as before) 
> s += "hello" # s is now "zsdhello" 
> s.object_id # prints 2171224560 (now it's different) 

parece que los caracteres individuales se puede cambiar w/o la creación de una nueva cadena. Sin embargo, agregar a la cadena aparentemente crea una nueva cadena.

¿Las cadenas en Ruby mutable?

+2

Sí, y responde a través de búsquedas triviales. http://stackoverflow.com/questions/2608493/why-did-matz-choose-to-make-strings-mutable-by-default-in-ruby –

+0

@DaveNewton: ¿No es genial lo fácil que es encontrar dúplex en SO, ya que casi puede contar con un tema SO que aparezca primero en google? –

+4

'+' es Concatenante y devolverá una nueva cadena. '<<' está Anexando y se agregará al objeto de cadena dado (no creará uno nuevo). – Chad

Respuesta

37

Sí, las cadenas en Ruby, a diferencia de Python, son mutables.

s += "hello" es no añadiendo "hello"-s - un completamente nuevo objeto cadena se crea. Para añadir a una cadena 'en su sitio', utilice <<, como en:

s = "hello" 
s << " world" 
s # hello world 
+3

¿Tiene sentido pensar en 'a + = b' como' a = a + b' en Ruby? Eso dejaría en claro por qué 's + =" hello "' crea una nueva cadena. – emlai

+1

@tuple_cat Sí, así es como se implementa '+ =', redefiniendo '+' produce un '' = = redefinido. – YoTengoUnLCD

8

Al añadir en Ruby String no es +=, es <<

Así que si cambia += a << su pregunta obtiene abordado por sí mismo

+3

+1. Como se explica en http://www.rubyfleebie.com/appending-to-a-string/, "' + = 'creará una nueva instancia de String y la asignará a su objeto izquierdo. Por otro lado,' << << 'agregará la nueva cadena directamente en su objeto izquierdo ya existente." – ruakh

11
ruby-1.9.3-p0 :026 > s="foo" 
=> "foo" 
ruby-1.9.3-p0 :027 > s.object_id 
=> 70120944881780 
ruby-1.9.3-p0 :028 > s<<"bar" 
=> "foobar" 
ruby-1.9.3-p0 :029 > s.object_id 
=> 70120944881780 
ruby-1.9.3-p0 :031 > s+="xxx" 
=> "foobarxxx" 
ruby-1.9.3-p0 :032 > s.object_id 
=> 70120961479860 

modo, las cadenas son mutables, pero += operador crea una nueva cadena. << mantiene viejo

6

cadenas en Ruby son mutables, pero se puede cambiar con la congelación.

irb(main):001:0> s = "foo".freeze 
=> "foo" 
irb(main):002:0> s << "bar" 
RuntimeError: can't modify frozen String 
0

De lo que puedo hacer de this pull request, llegará a ser posible en Ruby 3.0 para agregar un "comentario mágica" que hará toda la cadena inmutable, en lugar de mutable.

Porque parece que tiene que agregar explícitamente este comentario, parece que la respuesta a "¿es cadena mutable de forma predeterminada?" seguirá siendo sí, pero una especie de sí condicional depende de si usted escribió el comentario mágico en su secuencia de comandos o no.

EDITAR

me señaló a este bug/issue on Ruby-Lang.org que definitivamente afirma que algunos tipo de cadenas en Ruby 3.0 será de hecho inmutable por defecto.

1

Las cadenas de rubíes son mutables. Pero necesita usar < < para la concatenación en lugar de +.
De hecho concatenar cadena con
+ operador (inmutables) porque crea un nuevo objeto de cadena.
< < operador (mutable) porque cambia en el mismo objeto.

Cuestiones relacionadas