On Sat Jul 07 22:23:16 2012, thoughtstream wrote: > Father Chrysostomos asked: > > > What I am really trying to find out is when the subroutine is actually > > cloned, > > Yes. It is supposed to be (or at least must *appear* to be), > and currently is (or appears to be) in Rakudo.
I said when, not whether. :-) > > and whether there can be multiple clones within a single call of > > the enclosing sub. > > Yes. For example, a lexical sub might be declared in a loop inside the > enclosing sub, in which case it should produce multiple instances, one > per iteration. > > For example, this: > > sub outer_sub () { > for (1..3) { > state $call_num = 1; > my sub inner_sub { > state $inner_state = (1..100).pick; # i.e. random number > say " [call {$call_num++}] \$inner_state = $inner_state"; > } > > say "\nsub id: ", &inner_sub.id; > inner_sub(); > inner_sub(); > } > } > > outer_sub(); > > produces: > > sub id: -4628941774842748435 > [call 1] $inner_state = 89 > [call 2] $inner_state = 89 > > sub id: -4628941774848253711 > [call 3] $inner_state = 16 > [call 4] $inner_state = 16 > > sub id: -4628941774839825925 > [call 5] $inner_state = 26 > [call 6] $inner_state = 26 > > under Rakudo Thank you. Does Perl 6 have an equivalent to this? my $x; for $x(1..10) {} In this case, the loop reuses the $x slot in the pad, making the existing $x name an alias to a different scalar. But, due to the way Perl 5 closures work, it is, for all tents and porpoises, the same as this: my $x; for my $x(1..10) {} > BTW, Both the above "yes" answers are consistent with (and can be > inferred from) the previous explanation that: > > my sub foo { whatever() } > > is just a syntactic convenience for: > > my &foo := sub { whatever() } Except that my sub foo happens upon block entry, right? > > HTH, It does, but I am still trying to wrap my head around the fundamental difference between 5 and 6 with regard to closures. In Perl 5, $] in a piece of code is bound to *], not $], so it sees changes made by local($]) (which actually puts a completely new scalar in the *]{SCALAR} slot). But ‘my $x; sub { $x }’ is bound, not to the $x slot in the outer block/sub/file, but to the actual scalar itself. It seems that Perl 6 closures close over the slot, not the scalar/array/etc. Is that right? Anyway, I think I know how to implement this now. The first time a ‘my’ sub is referenced or called, it is cloned. The clone is stored for reuse, but that storage is localised to the current block. -- Father Chrysostomos