RubyIntermedio8 oct 2025
¡Atajos Peligrosos! La Mutación Silenciosa de Hashes
snippet.ruby
def add_default_value(hash, key, default_value = [])
hash[key] ||= default_value
end
hash1 = {}
add_default_value(hash1, :items)
hash1[:items] << 1
hash2 = {}
add_default_value(hash2, :items)
hash2[:items] << 2
puts hash1.inspect
puts hash2.inspect¿Qué crees que imprime?
✅ Salida Esperada
{:items=>[1]}
{:items=>[2]}⚠️ Salida Real
{:items=>[1, 2]}
{:items=>[1, 2]}¿Por qué pasa esto?
¡Oh, la pereza! 😅 En Ruby, el operador `||=` (o igual) puede ser un arma de doble filo. En este caso, estamos intentando inicializar un hash con un valor por defecto si la clave no existe. El problema es que `default_value = []` se evalúa solo una vez. ¡UNA SOLA VEZ! 😱
Esto significa que `hash1[:items]` y `hash2[:items]` apuntan al **MISMO** array en memoria. 🤯
Cuando modificamos `hash1[:items]`, ¡también estamos modificando `hash2[:items]` y viceversa! Es como si tuvieran la misma cuenta bancaria y uno le echa la culpa al otro de los gastos.
**Solución**: Crear una nueva instancia del array por defecto cada vez. Por ejemplo: `hash[key] ||= default_value.dup` o `hash[key] ||= []`.
Conceptos relacionados
hashmutationdefault-value