Ruby:哈希中的自引用

时间:2011-03-22 20:06:34

标签: ruby hash reference

是否可以在同一哈希中的另一个元素中引用哈希中的一个元素?

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

6 个答案:

答案 0 :(得分:14)

间接地也许......

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

puts foo[:hello].call

答案 1 :(得分:7)

如果您想让某些键的值依赖于其他键:

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'

答案 2 :(得分:4)

这不能直接完成,因为""是严格评估的。

需要使用延迟值生成器(例如lambda / proc)以及以后的评估。

快乐的编码。

答案 3 :(得分:2)

没有

至少不是一步到位。你可以这样做:

foo = {world: "hello"}
foo[:hello] = "Hello #{foo[:world]}"

答案 4 :(得分:0)

当然可以!

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

答案 5 :(得分:-1)

Object#tap为您提供了一种通过额外的自引用完成对象初始化的好方法。

{ foo: 1 }.tap { |obj| obj[:bar] = obj.fetch(:foo)}