Ruby Language Configuración de valores predeterminados


Ejemplo

De forma predeterminada, al intentar buscar el valor de una clave que no existe, se devolverá nil . Opcionalmente, puede especificar algún otro valor para devolver (o una acción a realizar) cuando se accede al hash con una clave que no existe. Si bien esto se conoce como "el valor predeterminado", no es necesario que sea un valor único; podría, por ejemplo, ser un valor computado como la longitud de la clave.

El valor predeterminado de un hash se puede pasar a su constructor:

h = Hash.new(0)

h[:hi] = 1 
puts h[:hi]  # => 1 
puts h[:bye] # => 0 returns default value instead of nil

Un valor predeterminado también se puede especificar en un hash ya construido:

my_hash = { human: 2, animal: 1 }
my_hash.default = 0
my_hash[:plant] # => 0

Es importante tener en cuenta que el valor predeterminado no se copia cada vez que se accede a una nueva clave, lo que puede generar resultados sorprendentes cuando el valor predeterminado es un tipo de referencia:

# Use an empty array as the default value
authors = Hash.new([])

# Append a book title 
authors[:homer] << 'The Odyssey'

# All new keys map to a reference to the same array:
authors[:plato] # => ['The Odyssey']

Para evitar este problema, el constructor de hash acepta un bloque que se ejecuta cada vez que se accede a una nueva clave, y el valor devuelto se utiliza como predeterminado:

authors = Hash.new { [] }

# Note that we're using += instead of <<, see below
authors[:homer] += ['The Odyssey']
authors[:plato] # => []

authors # => {:homer=>["The Odyssey"]}

Tenga en cuenta que anteriormente tuvimos que usar + = en lugar de << porque el valor predeterminado no se asigna automáticamente al hash; el uso de << se habría agregado a la matriz, pero los autores [: homer] habrían permanecido indefinidos:

authors[:homer] << 'The Odyssey' # ['The Odyssey']
authors[:homer] # => []
authors # => {}

Para poder asignar valores predeterminados en el acceso, así como para calcular valores predeterminados más sofisticados, el bloque predeterminado se pasa el hash y la clave:

authors = Hash.new { |hash, key| hash[key] = [] }

authors[:homer] << 'The Odyssey'
authors[:plato] # => []

authors # => {:homer=>["The Odyssey"], :plato=>[]}

También puede usar un bloque predeterminado para realizar una acción y / o devolver un valor dependiente de la clave (o algún otro dato):

chars = Hash.new { |hash,key| key.length }

chars[:test] # => 4

Incluso puedes crear hashes más complejos:

page_views = Hash.new { |hash, key| hash[key] = { count: 0, url: key } }
page_views["http://example.com"][:count] += 1
page_views # => {"http://example.com"=>{:count=>1, :url=>"http://example.com"}}

Para establecer el valor predeterminado en un Proc en un hash ya existente , use default_proc= :

authors = {}
authors.default_proc = proc { [] }

authors[:homer] += ['The Odyssey']
authors[:plato] # => []

authors # {:homer=>["The Odyssey"]}