How can I override my own Hash brackets ([] access)

I want to override my own Hash class brackets in ruby.

Note. I do not want to override them in a class that inherits from Hash (without a subclass), I want to actually override Hash, so any hash will always inherit my behavior.

In particular (bonus points for ..) - I want this to initially emulate a hash with indifferent access. In JavaScript, I would change prototype , Ruby is known for its metaprogramming, so I hope this is possible.

So what am I striving for:

 >> # what do I do here to overload Hash []?... >> x = {a:123} # x is a native Hash >> x[:a] # == 123, as usual >> x['a'] # == 123, hooray! 

I tried: 1)

 class Hash define_method(:[]) { |other| puts "Hi, "; puts other } end 

and

 class Hash def [] puts 'bar' end end 

Both crash irb.

+5
source share
2 answers

It seems that this work is done.

 class Hash def [](key) value = (fetch key, nil) || (fetch key.to_s, nil) || (fetch key.to_sym, nil) end def []=(key,val) if (key.is_a? String) || (key.is_a? Symbol) #clear if setting str/sym self.delete key.to_sym self.delete key.to_s end merge!({key => val}) end end 

And now:

 user = {name: 'Joe', 'age' => 20} #literal hash with both symbols and strings as keys user['name'] == 'Joe' # cool! user[:age] == 20 # cool! 

See http://www.sellarafaeli.com/blog/ruby_monkeypatching_friendly_hashes for details

+4
source
 class Hash def [] key value = fetch key rescue case key when Symbol then "#{value}, as usual" when String then "#{value}, hooray!" else value end end end 
+3
source

Source: https://habr.com/ru/post/1207535/


All Articles