2013-11-28 2 views
7

In знаю, что я могу управлять рубинового по умолчанию Hash значение, как это:Сжатый рубин хэш-эквивалент dict.get Python()

h={a:1, b:2, c:3} 
h[:x] # => nil 
h.default = 5 
h[:x] # => 5 
h.default = 8 
h[:y] # => 8 

, но это становится довольно утомительным, если делать это несколько раз для нескольких значений с различными по умолчанию ,

Он также может стать опасным, если хеш передается другим методам, которые хотят иметь собственные значения по умолчанию для определенных (потенциально отсутствующих) ключей.

В Python, я использовал

d={'a':1, 'b':2, 'c':3} 
d.get('x', 5) # => 5 
d.get('y', 8) # => 8 

, который не имеет каких-либо побочных эффектов. Есть ли эквивалент этого метода get в Ruby?

ответ

17

Да, это называется fetch, и он также может принимать блок:

h.fetch(:x, 5) 
h.fetch(:x) {|missing_key| "Unfortunately #{missing_key} is not available"} 
+0

Конечно! Не знаю, как я это пропустил. Благодаря! – FriendFX

0

Альтернатива #fetch это просто сделать что-то вроде этого:

h[:x] || 5 

недостающих ключей Питона поднять KeyError, но в Ruby отсутствующие ключи просто верните нуль.

Это имеет тонко различное значение, потому что по умолчанию будет происходить, если либо:

  1. ключ не в хэш
  2. ценность ключа в хэш уже nil

тогда как выборка будет только влиять на сценарий 1.

Ближайший эквивалент Python для этого кода

h.get('x') or 5 

(Заметим, однако, что это все-таки разные, поскольку truthiness/falsiness отличается в Python, чем в Ruby)

+0

3. Значение ключа в хэше уже «ложно». Таким образом, ваш ответ вовсе не эквивалентен 'dict.get()' –

+0

Я специально упомянул, что он не эквивалентен. Дело в том, что он достигает того, что может быть вашей целью с извлечением, а в тех случаях, когда поведение правильное, это более идиоматично. Некоторые из приложений dict.get Python не вызывают выборки, в то время как другие –

Смежные вопросы