On Apr 22, 6:15 pm, Daniel Finnie <d...@danfinnie.com> wrote:
> Hi,
> You can use super and/or alias:
> class MyHash < Hash > def [] key > super(key.downcase) > end > end
But he asking for case-insensitivity. If a key is created with uppercase letters, you're out of luck. And if you look for a value for a non-string key, that's no good either:
### class MyHash < Hash def [](key) super(key.downcase) end end
You could override []= as well (and with more care), but I wonder if a different class with a Hash instance variable with mediated access would be a better route.
> On Apr 22, 6:15 pm, Daniel Finnie <d...@danfinnie.com> wrote:
> > Hi,
> > You can use super and/or alias:
> > class MyHash < Hash > > def [] key > > super(key.downcase) > > end > > end
> But he asking for case-insensitivity. If a key is created with > uppercase letters, you're out of luck. And if you look for a value > for a non-string key, that's no good either:
> ### > class MyHash < Hash > def [](key) > super(key.downcase) > end > end
> You could override []= as well (and with more care), but I wonder if a > different class with a Hash instance variable with mediated access > would be a better route.
> But he asking for case-insensitivity. If a key is created with > uppercase letters, you're out of luck. And if you look for a value > for a non-string key, that's no good either:
Yeah, finally I've done:
class InsensitiveHash < Hash def [](key) find {|h| h[0] =~ /^#{key}$/i }[1] end end
> > But he asking for case-insensitivity. If a key is created with > > uppercase letters, you're out of luck. And if you look for a value > > for a non-string key, that's no good either:
> Yeah, finally I've done:
> class InsensitiveHash < Hash > def [](key) > find {|h| h[0] =~ /^#{key}$/i }[1] > end > end
> It works. :)
.. and is awfully inefficient.
Here's another way, which is more efficient for large hashes
class CiHash2 < DelegateClass(Hash) CiString = Struct.new :string do def to_s; string.downcase end def hash; string.downcase.hash end def eql?(s) string.downcase.eql? s.string.downcase end alias == eql? def inspect; string.inspect; end end
def initialize super({}) end
def []=(k,v) k = CiString.new(k) if String === k __getobj__[k] = v end
def [](k) k = CiString.new(k) if String === k __getobj__[k] end
# add other lookup and mutation methods end
h = CiHash2.new h["FOO"]=3 h["Foo"]=4 puts h["foo"] puts h["fOo"] p h
Cheers
robert
-- use.inject do |as, often| as.you_can - without end