this is very interesting. I think we should store this example somewhere in proper documentation format, maybe in docs/compiler_faq.pod
kjs On Feb 12, 2008 8:50 PM, Andrew Parker <[EMAIL PROTECTED]> wrote: > So that works in this situation because the outer lexpad that I want > is the same as the caller's lexpad. Thanks for the tip :) After > poking around a bit at what "getinterp" does I found some good reading. > > * docs/ops/core.pod - getinterp returns the ParrotInterpreter > * src/pmc/parrotinterpreter.pmc - the list of PMC keys is very > interesting > > Now to kick it up a notch! From that I learned that the getinterp and > then lexpad works in this case since the wanted lexical pad is the > caller's. This doesn't work when the wanted lexical pad is the > lexically enclosing scope (not the caller). Here is an example: > > # equivalent to: > # > # sub f { > # my $x = 1; > # return sub { my $x = $x + 1; return $x; }; > # } > # print f()->(), "\n" > # > .namespace > .sub "main" > get_global $P18, "outer" > $P17 = $P18() > $P16 = $P17() > print $P16 > print "\n" > .end > > .sub "outer" :outer("main") > new $P12, "Integer" > assign $P12, 1 > .lex "x", $P12 > get_global $P18, "inner" > newclosure $P18, $P18 > .return ($P18) > .end > > .sub "inner" :outer("outer") > $P0 = getinterp > $P1 = $P0['outer'; 'lexpad'] > $P14 = $P1['x'] > n_add $P15, $P14, 1 > .lex "x", $P15 > .return ($P15) > .end > > There is also the 'outer' lexpad which is the actuall enclosing one. > So it looks like my complaint that there was something lacking was > wrong. It is more that I didn't look enough and parrot has so much > that it was hard to find :P > > Thanks for the patience and the help. > > Andrew Parker > > On Feb 12, 2008, at 8:00 PM, Patrick R. Michaud wrote: > > > On Mon, Feb 11, 2008 at 10:27:27PM +0100, Andrew Parker wrote: > >> .namespace > >> .sub "outer" > >> new $P12, "Integer" > >> assign $P12, 1 > >> .lex "x", $P12 > >> get_global $P18, "inner" > >> newclosure $P18, $P18 > >> $P17 = $P18() > >> print $P17 > >> print "\n" > >> .end > >> > >> .sub "inner" :outer("outer") > >> find_lex $P14, "x" > >> n_add $P15, $P14, 1 > >> .lex "x", $P15 > >> .return ($P15) > >> .end > > > > A PIR subroutine can get at its caller's lexpad by doing: > > > > $P0 = getinterp > > $P1 = $P0['lexpad'; 1] > > > > So, in the 'inner' sub above, it can get to outer's 'x' lexical > > by doing: > > > > $P0 = getinterp > > $P1 = $P0['lexpad'; 1] > > $P2 = $P1['x'] > > > > Pm > >