Ruby: Self reference in hash
Is it possible to reference one element in a hash within another element in the same hash?
# Pseudo code
foo = { :world => "World", :hello 开发者_StackOverflow中文版=> "Hello #{foo[:world]}" }
foo[:hello] # => "Hello World"
Indirectly perhaps...
foo = { :world => 'World', :hello => lambda { "Hello #{foo[:world]}" }}
puts foo[:hello].call
If you want to make values of some keys dependent on others:
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'
This can't be done directly because ""
is strictly evaluated.
Use of a lazy-value generator (e.g. lambda/proc) with later evaluation is required.
Happy coding.
No.
At least not in one step. You could do something like:
foo = {world: "hello"}
foo[:hello] = "Hello #{foo[:world]}"
Sure you can!
options = { :deep => :stuff }
options.merge!(:options => options)
# It's the same at any depth...
options[:options][:options][:options][:options][:options]
#=> {:deep=>:stuff, :options=>{...}}
Neat, huh? The hash object in options
has the same object_id
as the value assigned to :options
.
Object#tap
gives you a nice way to complete the Object initialisation with extra self-references.
{ foo: 1 }.tap { |obj| obj[:bar] = obj.fetch(:foo)}
精彩评论