Создать хеш, используя блок (Ruby) - PullRequest
9 голосов
/ 08 сентября 2010

Могу ли я создать Ruby Hash из блока?

Как-то так (хотя это конкретно не работает):

foo = Hash.new do |f|
  f[:apple] = "red"
  f[:orange] = "orange"
  f[:grape] = "purple"
end

Ответы [ 5 ]

18 голосов
/ 08 сентября 2010

В Ruby 1.9 (или с загруженным ActiveSupport, например, в Rails) вы можете использовать Object#tap, например:

foo = Hash.new.tap do |bar|
  bar[:baz] = 'qux'
end

Вы можете передать блок в Hash.new, но это служит для определениязначения по умолчанию:

foo = Hash.new { |hsh, key| hsh[key] = 'baz qux' }
foo[:bar]   #=> 'baz qux'

Для чего бы это ни стоило, я предполагаю, что вы имеете в виду более крупную цель с этим блоком.Синтаксис { :foo => 'bar', :baz => 'qux' } может быть всем, что вам действительно нужно.

12 голосов
/ 08 сентября 2010

Я не могу понять, почему

foo = {
  :apple => "red",
  :orange => "orange",
  :grape => "purple"
}

у тебя не работает?

Я хотел опубликовать это как комментарий, но не смог найти кнопку, извините

4 голосов
/ 09 сентября 2010

Передача блока в Hash.new указывает, что происходит, когда вы запрашиваете несуществующий ключ.

foo = Hash.new do |f|
  f[:apple] = "red"
  f[:orange] = "orange"
  f[:grape] = "purple"
end
foo.inspect # => {}
foo[:nosuchvalue] # => "purple"
foo # => {:apple=>"red", :orange=>"orange", :grape=>"purple"}

При поиске несуществующего ключа перезаписываются любые существующие данные для :apple, :orange и :grape, вы не хотите, чтобы это произошло.

Вот ссылка на Hash.new спецификацию .

3 голосов
/ 08 сентября 2010

Что не так с

foo = {
  apple:  'red',
  orange: 'orange',
  grape:  'purple'
}
0 голосов
/ 11 февраля 2014

Как уже упоминалось, простой синтаксис хеша может дать вам то, что вы хотите.

# Standard hash
foo = {
  :apple => "red",
  :orange => "orange",
  :grape => "purple"
}

Но если вы используете метод "tap" или Hash с блочным методом, вы получите дополнительную гибкость, если вам нужно,Что делать, если мы не хотим добавить элемент в расположение яблока из-за какого-либо условия?Теперь мы можем сделать что-то вроде следующего:

# Tap or Block way...
foo = {}.tap do |hsh|
  hsh[:apple] = "red" if have_a_red_apple?
  hsh[:orange] = "orange" if have_an_orange?
  hsh[:grape] = "purple" if we_want_to_make_wine?
}
...