On Fri, May 13, 2005 at 11:54:47AM -0500, Patrick R. Michaud wrote:
: $r1 = rx / abc :: def | ghi :: jkl | mn :: op /;
: $r2 = rx / abc ::: def | ghi ::: jkl | mn ::: op /;
: $r3 = rx / [ abc :: def | ghi :: jkl | mn :: op ] /;
I would prefer that $r1 work like $r3, not like $r2, for two reasons.
First, it gives a useful distinction of meaning. Second, and more
importantly, outer lexical scopes are often delimited by something
other than what the inner scopes are delimited by. A file scope or an
eval string is no less a block because it's not delimited by curlies.
In the same way, the outer delimiters of an rx/.../ should function
as if you'd said rx/[...]/.
: However, *if* we say that :: at the top level fails the rule, that
: means that as things currently stand
: $z1 = rx :w /foo/;
: $z2 = rx /:w::foo/;
: $z3 = rx /[:w::foo]/;
: can be a little surprising:
: "hello foo" ~~ $z1 # matches "foo"
: "hello foo" ~~ $z2 # fails immediately upon the 'h' != 'f'
: "hello foo" ~~ $z3 # matches "foo"
: which was the point of my original post.
And that's the third reason. A :: at the beginning of a "group" should
essentially be a no-op.
By the way, I still think of it as "a group of alternatives" even
if there's only one alternative, and no |. But I can see how that
can be misread to imply at least two alternatives. (We're also
hampered by the linguistic fact that "alternative" can mean either
how many choices you have to make or how many paths are open to you.
In other words, one alternative of the first sort presents you two
alternatives of the second sort. And if there's no alternative, you
only have one alternative. Ain't English wonderful?
Anyway, :: fails the current lexical scope, not the current rule.
::: fails the current rule in a more dynamically scoped way, which
is why it also fails the engine applying the implicit .*?. And of
course, failure to <commit> is almost completely dynamic in scoping.
It's more like unwinding an exception till you find a handler that
knows it's the outer rule.