I am trying this example myhash = {/(\\d+)/ => \"hello\"}
with ruby 1.9.2p136 (2010-12-25) [i386-mingw32].
It doesn\'t work as exp
It will not work without some extra code, as it is you are comparing a Regexp object with either an Integer or a String object. They won't be value equal, nor identity equal. They would match but that requires changes to the Hash class code.
irb(main):001:0> /(\d+)/.class
=> Regexp
irb(main):002:0> 2222.class
=> Fixnum
irb(main):003:0> '2222'.class
=> String
irb(main):004:0> /(\d+)/==2222
=> false
irb(main):007:0> /(\d+)/=='2222'
=> false
irb(main):009:0> /(\d+)/.equal?'2222'
=> false
irb(main):010:0> /(\d+)/.equal?2222
=> false
you would have to iterate the hash and use =~ in something like:
hash.each do |k,v|
unless (k=~whatever.to_s).nil?
puts v
end
end
or change the Hash class to try =~ in addition to the normal matching conditions. (I think that last option would be difficult, in mri the Hash class seems to have a lot of C code)
Are you looking for this behaviour?
myhash = Hash.new{|h,k| h[k] = 'hello' if k =~ /(\d+)/}
p myhash['aaa'] #=> nil
p myhash #=> {}
p myhash['1234'] #=>" hello"
p myhash #=> {"1234"=>"hello"}
There is now a gem called Hashie that provides this feature (and much more): https://github.com/intridea/hashie#rash
It provides a data structure called Rash (short for regex-hash) that can be used like this
myhash = {/(\d+)/ => "hello"}
rash = Hashie::Rash.new(myhash)
>> rash["2222"]
=> "hello"
It really tries to match the key against the regexes so numeric keys won't work unless you convert them to string, which you can do easily by inheriting Rash into your own class
It never occurred to me to use a regex as a hash key. I'm honestly not sure if that should work, nor exactly how it would work if it should.
In any case, two thoughts:
hash
, but the hash is named myhash
.If I play around with it, I get these results:
hektor ~ ❯❯ irb
>> myhash = {/(\d+)/ => "hello"}
=> {/(\d+)/=>"hello"}
>> myhash['2222']
=> nil
>> myhash[2222]
=> nil
>> myhash[/(\d+)/]
=> "hello"
This is using Ruby 1.9.2-p180.
Ok, checked and here's what works:
myhash = {/foo/ => "hello"}
myhash[/foo/] # => "hello"
The lookup is on the key, and the key is a regex, not one of the many potential matches of that regex.
You can put Jean's answer in a default_proc
MAP = {
/1/ => "one",
/2/ => "two",
/\d/ => "number"
}
MAP.default_proc = lambda do |hash, lookup|
hash.each_pair do |key, value|
return value if key =~ lookup
end
return nil
end
p MAP["2"] #=> "two"
p MAP[44] #=> "number"