Reputation: 168101
What is the best way to construct a hash-like class Case
, which is initialized by a hash:
cs = Case.new(:a => 1, /b/ => 2, /c/ => 2, /d/ => 3)
and has a method Case#[]
that looks up for the first matching key by ===
(like a case statement) instead of by ==
(like the conventional hash) and returns the value:
cs["xxb"] => 2
Upvotes: 0
Views: 138
Reputation: 110685
Here's a possibility.
class Case
def initialize(h)
@h = h
end
def [](key,order=:PRE)
case order
when :PRE
h[@h.keys.find { |k| key === k }]
when :POST
h[@h.keys.find { |k| k === key }]
else
# raise exception
end
end
end
cs = Case.new(:a => 1, /b/ => 2, /c/ => 2, [1,2] => "cat", /d/ => 3)
cs["xxb"] #=> nil
cs["xxb",:POST] #=> 2
cs[Regexp] #=> 2
cs[Regexp,:POST] #=> nil
cs[Array] #=> "cat"
cs[Symbol] #=> 1
This assumes h
does not have a key nil
.
===
, the code would be:
class Case
def initialize(h) @h = h end
def [](key) h[@h.keys.find{|k| k === key}] end
end
Upvotes: 2