Hi, all. I was fixing a bug last night, and discovered some
“gotcha”-like behaviour in the process. Consider:
irb(main):173:0> s = “my string”
=> “my string”
irb(main):174:0> r1 = /my/
irb(main):175:0> r2 = /your/
irb(main):176:0> r3 = nil
irb(main):177:0> s =~ r1
irb(main):178:0> s =~ r2
irb(main):179:0> s =~ r3
s =~ r1 … That’s cool, it gives me the index of the match.
s =~ r2 … That’s cool, it tells me there was no match.
s =~ r3 … Whoa.
The reason this “got me” is that I had this code:
match_result = ( some_string =~ some_regexp )
if match_result != nil
# Assume there was a match
But the problem is… I had an s =~ r3 case because some_regexp was nil,
and so it was entering my if block when I semantically did not want that
So now my code is
if match_result != nil and match_result != false
Note also that I can’t even use Regexp.last_match != nil in my if block:
irb(main):224:0> s =~ r2
irb(main):226:0> s =~ r3
irb(main):228:0> s =~ r1
irb(main):230:0> s =~ r3
To be clear: Note how a “nil type” of non-match overwrites last_match,
but a “false type” of non-match doesn’t.
So the question is… why are BOTH nil and false possible return values
of =~ ? Is there some benefit to this? Why not just one or the other?
I see that this behaviour is documented but I still feel that this
is unintuitive behaviour when people assume =~ only applies to Regexp
Thanks in advance for any and all clarifications and explanations.