Ruby Language Impostazione dei valori predefiniti

Esempio

Per impostazione predefinita, il tentativo di cercare il valore per una chiave che non esiste restituirà nil . È possibile specificare facoltativamente un altro valore da restituire (o un'azione da eseguire) quando si accede all'hash con una chiave inesistente. Anche se questo è indicato come "il valore predefinito", non è necessario che sia un singolo valore; potrebbe, ad esempio, essere un valore calcolato come la lunghezza della chiave.

Il valore predefinito di un hash può essere passato al suo costruttore:

h = Hash.new(0)

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

Un valore predefinito può anche essere specificato su un hash già creato:

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

È importante notare che il valore predefinito non viene copiato ogni volta che si accede a una nuova chiave, il che può portare a risultati sorprendenti quando il valore predefinito è un tipo di riferimento:

# 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']

Per ovviare a questo problema, il costruttore Hash accetta un blocco che viene eseguito ogni volta che si accede a una nuova chiave e il valore restituito viene utilizzato come predefinito:

authors = Hash.new { [] }

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

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

Nota che sopra abbiamo dovuto usare + = invece di << perché il valore predefinito non è assegnato automaticamente all'hash; usando << sarebbe stato aggiunto all'array, ma gli autori [: homer] sarebbero rimasti indefiniti:

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

Per poter assegnare valori predefiniti all'accesso, nonché per calcolare valori predefiniti più sofisticati, il blocco predefinito viene passato sia all'hash che alla chiave:

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

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

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

Puoi anche utilizzare un blocco predefinito per eseguire un'azione e / o restituire un valore dipendente dalla chiave (o da altri dati):

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

chars[:test] # => 4

Puoi persino creare hash più complessi:

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"}}

Per impostare l'impostazione predefinita su Proc su un hash già esistente , usa default_proc= :

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

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

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