2014-11-23 3 views
5

Ich möchte die Klasse Hash nativen Klammern in Ruby außer Kraft zu setzen.Wie kann ich überschreiben Hash nativen Klammern ([] access)

Hinweis Ich möchte sie nicht in einer Klasse überschreiben, die von Hash (keine Unterklasse) erbt, ich möchte Hash selbst überschreiben, so dass jeder Hash irgendwo mein Verhalten immer erben wird.

Speziell (Bonuspunkte für ..) - Ich möchte dies, um nativ emulieren Hash mit indifferent Zugriff. In JavaScript würde ich die prototype ändern, Ruby ist bekannt für seine Metaprogrammierung, also hoffe ich, dass dies möglich ist.

Also, was ich bin mit dem Ziel für ist:

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

Ich habe versucht: 1)

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

und

class Hash 
    def [] 
    puts 'bar' 
    end 
end 

Beide Absturz irb.

+3

Bitte zeigen, was haben Sie versucht, so weit –

+2

uns zeigen, was haben Sie –

+0

versucht Uh ... zwei Ansätze zum Beispiel (das kann nicht vom Boden aufkommen, irb stürzt ab, wenn man sie laufen lässt): 1) Klasse Hash; define_method (: []) {| andere | setzt "Hallo"; setzt andere} Ende 2) Klasse Hash; def [] (Schlüssel) setzt den Schlüssel; Ende erwähnenswert, dass es möglich ist, in einer Unterklasse außer Kraft zu setzen (http://stackoverflow.com/a/974442/954741), aber ich kann nicht verwalten nativen Hashes außer Kraft zu setzen. – sellarafaeli

Antwort

4

Dies scheint die Arbeit zu erledigen.

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 

Und jetzt:

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

Weitere Informationen finden Sie unter: http://www.sellarafaeli.com/blog/ruby_monkeypatching_friendly_hashes

+1

@sellarfaeli, wenn Sie mehr als Rubyist aufwachsen, werden Sie gute Erinnerungen an Ihren dummen jugendlichen Abenteuer haben mit zwingenden 'Hash # []' und '# [] = 'lol. –

3
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 
+0

Auch funktioniert nicht über Ruby-Versionen, weil irb. Irb ist ein Sonderfall. –

+0

stürzt mein irb. Aber brachte mich sehr nahe (siehe meine Antwort) so upvoting! Vielen Dank! – sellarafaeli

Verwandte Themen