Wow. That's some ugly ruby.
So num
here is actually a String
(the tip offs being the use of the #sub
and #=~
methods.
list
is an Array
of
Regexp
objects and/or
- pairs of
Regexp
and replacement String
objects.
If none of the given Regexp
s match the string, the method returns nil
.
If an unpaired Regexp
matches the string, the method returns that Regexp
.
If a paired Regexp
matches the string, the method substitutes the part of the string
that the Regexp
matches with the paired replacement text, and returns the modified String
.
Once a Regexp
matches the string, the method returns - no later Regexp
s are considered.
In no cases is the original String
modified.
It's really a franken-method, IMHO, since it's trying to do very different things.
An example call:
in_list("abe lincoln", [ [/linc/, 'zelda'] ]) #=> "abe zeldaoln"
in_list("abe lincoln", [ [/linc/] ]) #=> /linc/
in_list("abe lincoln", [ [/link/] ]) #=> nil
Really, with that multitude of return types, it seems like more of a pain in the ass than it's worth.
In pseudo-code
DEF IN-LIST( text, regexps )
FOREACH regexp IN regexps
IF HAS-MATCH( text, regexp )
IF HAS-REPLACEMENT-TEXT( regexp )
RETURN REPLACE-MATCHED-PORTION( text, regexp, GET-REPLACEMENT-TEXT(regexp) )
ELSE
RETURN regexp
ENDIF
ENDIF
ENDFOREACH
RETURN NOTHING-FOUND
ENDDEF
But like I said, this is some ugly-ass ruby. I'd avoid using it. It's a codesmell that tells me there's a whole lot wrong with this code.
If I had an array of Regexps
, and wanted to find the first one that matched some text, I'd do:
# general case
regexps.find { |re| text =~ re }
# example
[ /earn/, /more/, /sessions/, /by/, /sleaving/ ].find { |re| "A baby?" =~ re } # would return /by/
If I had an collection of Regexp
, replacement text pairs, and I wanted to replace the first match in some text, I'd do this
# general case
text_dupe = text.dup
pairs.find { |re,replace| text_dupe.sub!( re, replace ) }
# example
text_dupe = "One two three four".dup
[ [/ape/, 'frog'], [/our/, 'my'] ].find { |re,replace| text_dupe.sub!( re, replace } } # would return "One two three fmy"
I'd rather use a Hash
for the last actually, but since that loses the order the original list came in (and who am I to say
that's not important, not knowing how it's used), I didn't.