Ruby Hashes pode fazer algumas coisas muito legais, dependendo de como você os cria.
>> h = Hash.new
=> {}
>> h[:foo]
=> nil
>> h.keys
=> []
Ok, nada de louco aí. Hash.new
pode assumir um valor, que se tornará o valor padrão retornado se uma chave não for encontrada no hash.
>> h = Hash.new('bacon')
=> {}
>> h[:foo]
=> "bacon"
>> h.keys
=> []
Tudo bem, muito legal. Não tenho certeza de por que você pode querer fazer isso, mas acho que é uma boa maneira de evitar o temido nil
. Podemos usar essa construção para criar um contador barato.
>> h = Hash.new(0)
=> {}
>> h[:foo]
=> 0
>> h[:foo] += 1
=> 1
>> h.keys
=> [:foo]
>> h[:foo] += 1
=> 2
>> h[:foo] += 1
=> 3
>> h[:foo]
=> 3
Muito legal. Qual o proximo? Que tal um bloco? Os argumentos (?) Para o bloco representam o próprio hash ( h
) e a chave sendo acessada ( k
). Podemos usar isso para criar um hash que se preencherá automaticamente com o valor da chave que está sendo chamada.
>> h = Hash.new { |h,k| h[k] = k }
=> {}
>> h['foo']
=> "foo"
>> h.keys
=> ["foo"]
>> h['foo']
=> "foo"
>> h.keys
=> ["foo"]
Ok, não é muito útil, mas e se definirmos o valor da chave para buscar a chave como uma solicitação HTTP?
>> require 'httparty'
=> true
>> h = Hash.new { |h,k| h[k] = HTTParty.get(k).body }
=> {}
>> h['http://rodreegez.com']
=> # takes a while, but returns the HTML of my personal site
>> h['http://rodreegez.com']
=> # returns instantly the same HTML
Estrondo. A construção de cache mais barata disponível para o homem. Talvez. Recomendo que você experimente esse último. Provavelmente é inútil, mas meio divertido.
Espero que você tenha isso em mente da próxima vez que usar um hash. Pode ser útil!
Eu peguei a maior parte dos itens acima aqui: http://endofline.wordpress.com/2010/12/24/hash-tricks/