Рубин: ссылка на себя в хэш - PullRequest
19 голосов
/ 22 марта 2011

Можно ли ссылаться на один элемент в хеше внутри другого элемента в том же хеше?

# Pseudo code
foo = { :world => "World", :hello => "Hello #{foo[:world]}" }
foo[:hello] # => "Hello World"

Ответы [ 6 ]

14 голосов
/ 22 марта 2011

Возможно, косвенно ...

foo = { :world => 'World', :hello => lambda { "Hello #{foo[:world]}" }}

puts foo[:hello].call
7 голосов
/ 22 марта 2011

Если вы хотите, чтобы значения некоторых ключей зависели от других:

foo = Hash.new{|h, k|
   case k
   when :hello; "Hello #{h[:world]}"
   when :bye; "Bye #{h[:world]}"
   end
}
foo[:world] = 'World'
foo[:hello] # => 'Hello World'
foo[:bye] # => 'Bye World'
foo[:world] = 'Heaven'
foo[:hello] # => 'Hello Heaven'
foo[:bye] # => 'Bye Heaven'
4 голосов
/ 22 марта 2011

Этого нельзя сделать напрямую, поскольку строго оценивается "".

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

Happyкодирование.

2 голосов
/ 22 марта 2011

Нет.

По крайней мере, не за один шаг.Вы можете сделать что-то вроде:

foo = {world: "hello"}
foo[:hello] = "Hello #{foo[:world]}"
0 голосов
/ 16 ноября 2018

Object#tap дает вам хороший способ завершить инициализацию объекта с помощью дополнительных собственных ссылок.

{ foo: 1 }.tap { |obj| obj[:bar] = obj.fetch(:foo)}
0 голосов
/ 21 ноября 2013

Конечно, вы можете!

options = { :deep => :stuff }
options.merge!(:options => options)

# It's the same at any depth...
options[:options][:options][:options][:options][:options]
  #=> {:deep=>:stuff, :options=>{...}}

Аккуратно, а?Хеш-объект в options имеет то же object_id, что и значение, присвоенное :options.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...