¿Por qué la ausencia del operador de asignación me permite modificar una constante Rubí sin advertencia del compilador?

StackOverflow https://stackoverflow.com/questions/670094

Pregunta

En los dos ejemplos siguientes hago lo mismo, la creación de una cadena constante y utilizando el método concat para modificarlo. Debido a que es una constante, espero una advertencia del compilador, pero sólo recibo sola en el segundo ejemplo cuando se utiliza el operador de asignación. ¿Por qué es esto?

X = "hello"
X.concat(" world")
puts X # no warning

X = "hello"
X = X.concat(" world")
puts X # warning: already initialized

Dado que el método concat modifica la secuencia en el lugar, eso es lo que normalmente lo haría, ya que no hay necesidad de utilizar un operador assigment. Así que, ¿por qué la presencia del operador de asignación que el compilador para identificar estas dos operaciones como diferente?

¿Fue útil?

Solución

Esto se debe a que está re-definición de un nuevo X. Al volver a definir una constante que le da el error "que ya está iniciado". El primer ejemplo no da este error porque no está redefiniendo X, que se está modificando a él.

Otros consejos

En Ruby, variables son esencialmente punteros a un lugar en una memoria que contiene un objeto - no el propio objeto. En el segundo ejemplo, se está inicializando una constante X para apuntar a un objeto en la primera línea (X = "hello") y, en la segunda línea, que está de nuevo Inicialización de la constante - pero ya apunta a un objeto, para que pueda obtener el error.

inmutabilidad de una constante no significa que no pueda alterar el objeto - sólo significa que no se puede cambiar la constante para apuntar a otro objetos

.

Si desea hacer su cadena "real" constante, trate de 'congelar':

X = "foo".freeze        # => "foo" 
X.concat("bar")

TypeError: can't modify frozen string
    from (irb):2:in `concat'
    from (irb):2

Me animo a leer El rubí de programación Languge .

Esto es porque el X constante es el almacenamiento de una referencia a un objeto String. En el primer ejemplo, se está modificando el estado interno del objeto concat, pero no la referencia almacenada por la constante. En el segundo ejemplo, que está cambiando la referencia almacenada por la constante a un nuevo objeto <=> que se devuelve desde el método <=>.

El libro explica este pico aquí .

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top