A common point of confusion for some Citrus users is that they are not able to retrieve a match by calling its own name on itself. This commit adds self to the internal @captures Hash in the first position. Also, Match#to_a and Match# were added for convenience when retrieving captures and submatches.
All example test suites are run with the default Rake test task. This ensures that examples are always working with the current version of the code. Also, Citrus.require should raise Citrus::LoadError if it cannot find a suitable file to load.
Added the ability for require statements inside Citrus files to require other Citrus files that may be in the $LOAD_PATH. Also, modified the behavior of Citrus.load to cache the result of already loaded files so that we don't load the same file twice. Modified examples/ipaddress.citrus to demonstrate the use of require from within Citrus files.
This restores the former behavior to matches that are the results of a Choice rule, which is that they are essentially the same match as is returned by the first matching rule of that choice. This largely eliminates the need to call Match#first in the value blocks of choices, which feels more natural when writing them.
Match#captures is the preferred method of retrieving named sub-captures when performing match evaluation. It's easier to use than Match#matches because it provides direct access to matches as they were written in the rule definition, without requiring the user to think about how the actual match tree was constructed. This commit deprecates Match#name, Match#names, Match#has_name?, Match#find, and match naming in general. Matches should not keep track of the names of the rules that created them since that information can be derived as needed from the event stream as demonstrated by Match#captures. Also, Citrus::NoMatchError was eliminated to favor a more fluid style of use when using Match#method_missing to find a capture of a given name.
This commit introduces a number of incompatibilities with previous versions. The most significant changes are listed below. - Rule, Proxy, and Nonterminal are modules. This is because they should never be instantiated directly. - Labels are stored as a symbol on the rule object that has them. This eliminates the unnecessary wrap in the event stream. - Proxy objects do not wrap the events of the rule they are proxy for in the event stream. Instead, they simply insert themselves into the event stream in its place. This allows them to maintain the nesting level of the original rule in the event stream, while still giving them the opportunity to extend matches themselves. - Choice objects no longer automatically return the value of their first match. While this technique was convenient in some situations, it was also a bit unpredictable and confusing for some users. Making it behave like all other nonterminals is more predictable and easier to handle in the code as well.