On Thu, Mar 11, 2004 at 01:09:59AM -0500, Austin Hastings wrote:
: 
: 
: > -----Original Message-----
: > From: Damian Conway [mailto:[EMAIL PROTECTED]
: > Sent: Wednesday, 10 March, 2004 09:48 PM
: > To: [EMAIL PROTECTED]
: > Subject: Re: Mutating methods
: >
: >
: > Brent "Dax" Royal-Gordon wrote:
: >
: > >>     / $foo:=(abc) $bar:=(def) /
: > >
: > > Am I misreading, or are you suggesting that $foo may contain
: > 'abc' after
: > > running this example, even if the match wasn't successful?
: >
: > No. I re-checked with Larry this morning and he confirmed that
: > all bindings in
: > rules only "stick" if the rule as a whole succeeds.
: >
: > What I was trying (obviously rather ineptly ;-) to point out is
: > that we have
: > to be able to differentiate between the the match object's own internal
: > hypothetical variables ($?foo, $?bar, @?baz) and any
: > external-but-temporarily-hypothesized variables ($foo, $bar, @baz).
: >
: > The syntax we've chosen to do that requires the use of "?" as a secondary
: > sigil on internal variables. So, since named subrules that capture always
: > capture to internal variables, it's natural and consistent to use "?" to
: > indicate capturing subrules as well.
: 
: Isn't this backwards?
: 
: That is, from the above I get the impression that $?foo is TRANSIENT, while
: capturing to $foo will (eventually) be PERMANENT.

$?foo is exactly as transient as the $0 in which it resides.  So it
really depends on how long $0 lives outside the regex.  In the case
of a returned parse tree it could live a very long time.

: So <?foo> is just a shorthand way of saying
: 
:    $?foo := <foo>
: 
: right?

Yes.  The ? is actually serving as a scope marker telling Perl not
to scan outside of the current regex for a variable of that name.
If you consider each rule to be its own package, it's kind of an "our"
declaration within the rule.

: Is hypo-space a flat entity, or do hypothetical scopes nest?

Um, the namespace inside a particular rule is flat, just as the
namespace inside a package is flat.  That doesn't mean that your code
won't visit those variables in whatever order it jolly well pleases.
Dynamically speaking, every assertion in a regex is recursively matched "inside"
the results of previous successful assertions, regardless of the
lexical structure of the rule.  You're often in situations where dynamically
you're going down recursively, while in terms of where you are in the
match, you're going out of brackets or parens.  It has to be that way,
or you could never backtrack into a set of brackets or parents.

But once a subrule is matched, all its ? names are bundled up into
a hash in the single "$0"-ish object that becomes aliased (at least
temporarily) to the $?foo in the outer rule.  The keys of that hash are
flat for all the names in the particular rule, though of course some
of the values may be nested $0 results from subrules.  So effectively
you end up with a hash of hash of hash of hash....  representing the
entire syntax tree.  But any given rule can't produce more than one
level of hash (without doing something freaky like rewriting your
hash entries inside a closure).

: If so, do we
: have to use repeated ?'s, or will just one suffice?
: 
: That is:
: 
:    rule bar {...}
:    rule baz {...}
:    rule foo {...bar...baz...}
: 
:    if / <?foo> ... <?baz> ... { $?foo.?baz ... $?baz } .../
: OR
:    if / <?foo> ... <?baz> ... { $?foo.baz ... $?baz } .../
: OR
:    if / <?foo> ... <?baz> ... { $?baz ... $?otherbaz } .../

Well, you don't need "?" to go down the syntax tree, since each $0
can behave as a hash.  You don't subscript hashes using "." either.
You subscript hashes with {...} historically, or these days, «...»,
when you want constant subscripts.  So what you're looking for is
something like:

    if / <?foo> ... <?baz> ... { $?foo{'baz'} ... $?baz } .../

or

    if / <?foo> ... <?baz> ... { $?foo«baz» ... $?baz } .../

or even:

    if / <?foo> ... <?baz> ... { $0«foo»«baz» ... $0«baz» } .../

Oh, and since the current $0 is actually the topic of any closure,
you can also probably say

    if / <?foo> ... <?baz> ... { .«foo»«baz» ... .«baz» } .../

as an analog to

    if / <?foo> ... <?baz> ... { .{'foo'}{'baz'} ... .{'baz'} } .../

That's presuming we keep the rule that scalars don't have to include
the sigils.  For an array you'd still have to say:

    if / @?things:=[ (<ident>) ,? ]+ { ... [EMAIL PROTECTED] ... } /

or

    if / @?things:=[ (<ident>) ,? ]+ { ... [EMAIL PROTECTED] ... } /

But then it's usually easier just to say

    if / @?things:=[ (<ident>) ,? ]+ { ... @?things ... } /

which means exactly the same thing.

Larry

Reply via email to