verbal_expressions
verbal_expressions copied to clipboard
"Alternatively" gives unexpected behaviour
def alternatively(value = nil)
@prefixes += "(?:" unless @prefixes.include?("(")
@suffixes = ")" + @suffixes unless @suffixes.include?(")")
add(")|(?:")
find(value) if value
end
I don't like this abuse of the @prefixes
and @suffixes
. Especially given that we also have the methods:
def start_of_line(enable = true)
@prefixes = '^' if enable
end
def end_of_line(enable=true)
@suffixes = '$' if enable
end
For example, the following code creates an invalid RegEx:
VerEx.new do
find 'a'
alternatively
find 'b'
end_of_line
end
(The @suffixes
gets overwritten by end_of_line
, so we are left with a trailing bracket.)
There were two possible solutions to this: Fix the end_of_line
method by using +=
rather than just =
, or (what I chose to do instead):
def start_of_line
add('^')
end
def end_of_line
add('$')
end
This gives the important added benefit that we can now match start/end of lines in the middle of strings!
However, with the new code I wrote, we can still end up with slightly unexpected behaviour such as:
VerEx.new do
start_of_line
find 'a'
alternatively
find 'b'
end
#=> /(?:^a)|(?:b)
Rather than ^(?:a)|(?:b)/
, as one might expect. In order to achieve this, our VerEx would have needed to be:
VerEx.new do
start_of_line
find 'a'
alternatively
start_of_line
find 'b'
end
#=> /(?:^a)|(?^:b)
This is a slight change in behaviour.
Basically, to cut a long story short, this alternatively
method may be simple and powerful, but must be used with caution. A little usage example, such as the one I gave above, would be a good idea for the README.