On 18/02/06 03:10, Larry Wall wrote:
On Sat, Feb 18, 2006 at 01:57:18AM +0200, Brad Bowman wrote:
: $a is spliced into the say as either a string or AST, not
: as a runtime use of $a. If the snippet was:
:
: $a = '$a';
: return CODE { say $a };
:
: Then we'd (eventually) get a non-splicing mention of $a, one that
: would refer to the $a in scope at the macro call, I think.
: Is this correct?
No. If bare $a is not found in the CODE's scope, it must *bind* to
an existing $a in the macro caller's scope as a runtime use of $a,
I was intending the above example to satisfy the "$a in the CODE's scope"
clause, I was missing a "my". I think my example doesn't achieve
it's goal anyway. I'll try again:
macro M ($a) {
my $b = '$c';
return CODE { $a + $b };
}
package Elsewhere;
my ($b, $c, $d) = (1,2,3);
say M($d + 2);
The macro parameter $a is bound to the ast for COMPILING::<$d> + 2
The $a mentioned in the CODE is replace with the same, roughly:
CODE { COMPILING::<$d> + 2 + $b }
$b exists in the lexical scope of the CODE block, so it is preferred.
Since $b is a string, '$c' replaces $b in the above and parsing
is restarted there. Once $c is parsed, the macro's scope is searched
and fails. (This is where I derailed the first time round)
CODE { COMPILING::<$d> + 2 + $c }
The $c is free and so must bind to an existing $c in the scope of the
macro call, which is fine in this example. The result is a complicated 7.
I guess I was unclear about the effect of the $b='$c' indirection,
it seems like the answer is that there is no effect, the $c is
bound and spliced just as the original $b is.
or the macro fails. If the calling code wants to supply arguments
to the macro body, they must come in as ordinary arguments, or use
some modifier that chases up the dynamic stack, such as one of
CALLER::<$a>
ENV::<$a>
COMPILING::<$a>
These are non-splicing mentions of variables from the call site (right?).
Is there a way to do a non-splicing mention of variables at the macro
definition site, similar to normal code closures?
The CODE can mention sub names, they're not spliced and thus give the
indirection I was looking for. (I think)
my $counter;
sub inc_counter { return $counter++; }
macro c {
return CODE { inc_counter() };
}
A state variable declared within the CODE would also suffice in this case.
: --
: When one is not capable of true intelligence, it is good to consult with
: someone of good sense. -- Hagakure http://bereft.net/hagakure/
It's not entirely clear to me that we should trust the advice of someone
who was prevented from committing seppuku only by edict of Tokugawa. :-)
Yeah! Where's his mettle?
But the scary part about that quote is that it seems to be saying that
if you have true intelligence you don't need good sense.
Maybe it was lost in translation. Or maybe those of true intelligence
can work it out themselves, without needing the advice of a cranky samurai. :)
--
... One should think well then speak. ... -- Hagakure