ruby hash with self referencing elements / recursive hash
I need a ruby hash H with keys :a, :b, :c so that H[:b] = H[:a] + 1; H[:c] = H[:b] + 2 etc.
How can I define such a hash in a one line declaration, like H = {:a=>1, :b => H[:a] + 1, :c => H[:b] +2, ... } ?
I need something similar to DataMapper properties declaration:
property :path, FilePath
property :md5sum, String, :default => lambda { |r, p| Digest::MD5.hexdigest(r.path.read)}
w开发者_开发问答here :md5sum default value is referencing the :path property
This is the best I can do:
arr = [[:a,1], [:b,1], [:c,2]]; H = {:temp => 0}
arr.inject(:temp) { |last, kv| H[kv[0]] = H[last] + kv[1]; kv[0] }
H.delete :temp
Pretty ugly, and it isn't so obvious what it does. I suggest you just do it the straightforward way, unless it's really that much of a problem.
It's not clear what you are trying to accomplish. Note that hashes can have a default proc. Ex:
require 'digest/md5'
h = Hash.new do |hash, key|
hash[:md5sum] = Digest::MD5.hexdigest(hash[:path]) if key == :md5sum
end
h[:path] = "/starway/to/heaven"
h[:md5sum] # ==> "0e4faf226dac83569bde4fcf5bcd7ad6"
h[:md5sum] = "xyz"
h[:md5sum] # ==> "xyz"
It sounds like you may want lazy declarations: http://moonbase.rydia.net/software/lazy.rb/
精彩评论