Aprende a programar con Ruby

Congelando objetos

Los objetos inmutables son aquellos que no pueden cambiar de estado después de ser creados. Las propiedades por las que destacan son:

  • ser thread-safe. Los threads no pueden corromper lo que no pueden cambiar.
  • facilitar el implementar la encapsulación: si parte del estado de un objeto es almacenado dentro un objeto inmutable, entonces los métodos modificadores pueden leer el estado de dicho objeto, sin miedo a que modifiquen su estado.
  • ser índices en los hashes inmutables, ya que no pueden cambiar.

En Ruby, la mutabilidad es una propiedad de los objetos, no de una clase entera. Cualquier objeto (o instancia) se puede volver inmutable usando freeze.

freeze

El método freeze (congelar) evita que un objeto pueda modificarse, convirtiéndolo en una constante. Después de "congelar" el objeto, cualquier intento de modificarlo da como resultado un TypeError.

str = 'Un simple string'
str.freeze # congelamos el string

# se intenta modificar (begin)
# y en caso de error (rescue)
# se lanza un mensaje. Ver Excepciones. 

begin  
  str << 'Intento de modificarlo'
rescue => err  
  puts "#{err.class} #{err}"  
end

La salida es - TypeError can't modify frozen string.

Sin embargo, freeze funciona con las referencias, no con las variables: esto significa que si creamos un objeto nuevo, y sobreescribimos la variable, este se podrá modificar:

str = 'string original - '
str.freeze
str += 'añadido a posteriori'
puts str

La salida es - 'Original string - añadido a posteriori'

El objeto original no cambió. Sin embargo, la variable str se refiere a un nuevo objeto. El método frozen? nos dice si un objeto está congelado o no.