| Version 1 (modified by Austin_Hastings, 3 years ago) |
|---|
The following code works as of Parrot 2.1 to create and store closures from NQP-rx. If you need this, please note that the newclosure op is necessary to clone the enclosed context. Also, you need to re-enter the containing lexical scope to reset the lex vars you want unshared. Otherwise, as shown (see shared vs. not_shared) they won't be shared.
#! /usr/bin/env parrot-nqp
MAIN();
sub MAIN() {
my @closures;
my @names := <fred wilma barney betty>;
{
my $shared := 1;
my $count := 1;
for @names -> $name {
my $not_shared := 1;
my &sub := {
say("$name\twas called $not_shared times. Any sub was called $shared times.");
$shared++;
$not_shared++;
};
@closures.push: pir::newclosure__PP( &sub );
$count++;
}
}
my $count := 0;
while $count < 3 {
for @closures {
$_();
}
$count++;
}
}
Entering Scope
It is the act of _entering_ the lexical block that performs the allocation of a new lexpad and the other housekeeping associated with a new lexical environment (for you to enclose). You can get that effect in a number of ways:
- Calling a sub, obviously, enters its lexical scope when you call it.
- Recursion, naturally, qualifies as entering a new lexical scope.
- Executing a for or while/until loop, because these are implemented as subs.
- Executing an if or unless statement that contains lexical variable declarations. (Caution! If the block has no lexical vars, it will be 'in-lined' and not a separate sub.)
