आप आलसी हो सकते हैं, और इसे इसमें लपेट सकते हैं lambda
:
my_hash = YAML.load_file('yml')
my_lamb = lambda { |key| my_hash[key.to_s] }
my_lamb[:a] == my_hash['a'] #=> true
लेकिन यह केवल हैश से पढ़ने के लिए काम करेगा - लेखन नहीं।
ऐसा करने के लिए, आप उपयोग कर सकते हैं Hash#merge
my_hash = Hash.new { |h,k| h[k] = h[k.to_s] }.merge(YAML.load_file('yml'))
इनिट ब्लॉक मांग पर एक बार चाबियाँ बदल देगा, हालांकि यदि आप प्रतीक संस्करण तक पहुंचने के बाद कुंजी के स्ट्रिंग संस्करण के लिए मान अपडेट करते हैं, तो प्रतीक संस्करण अपडेट नहीं किया जाएगा।
irb> x = { 'a' => 1, 'b' => 2 }
#=> {"a"=>1, "b"=>2}
irb> y = Hash.new { |h,k| h[k] = h[k.to_s] }.merge(x)
#=> {"a"=>1, "b"=>2}
irb> y[:a] # the key :a doesn't exist for y, so the init block is called
#=> 1
irb> y
#=> {"a"=>1, :a=>1, "b"=>2}
irb> y[:a] # the key :a now exists for y, so the init block is isn't called
#=> 1
irb> y['a'] = 3
#=> 3
irb> y
#=> {"a"=>3, :a=>1, "b"=>2}
आपके पास init ब्लॉक भी हैश को अपडेट नहीं कर सकता है, जो आपको उस तरह की त्रुटि से बचाएगा, लेकिन आप अभी भी इसके विपरीत होंगे - प्रतीक संस्करण को अपडेट करने से स्ट्रिंग संस्करण अपडेट नहीं होगा:
irb> q = { 'c' => 4, 'd' => 5 }
#=> {"c"=>4, "d"=>5}
irb> r = Hash.new { |h,k| h[k.to_s] }.merge(q)
#=> {"c"=>4, "d"=>5}
irb> r[:c] # init block is called
#=> 4
irb> r
#=> {"c"=>4, "d"=>5}
irb> r[:c] # init block is called again, since this key still isn't in r
#=> 4
irb> r[:c] = 7
#=> 7
irb> r
#=> {:c=>7, "c"=>4, "d"=>5}
इसलिए इनसे सावधान रहने की बात दो प्रमुख रूपों के बीच बदल रही है। एक के साथ रहना।