Rod Adams <[EMAIL PROTECTED]> writes:

> Piers Cawley wrote:
>
>>Chip and I have been having a discussion. I want to write:
>>
>>    sub foo { my $x = 1; return sub { eval $^codestring } }
>>    say foo()("$x");
>>
>>I claim that that should print 1. Chip claims it should throw a warning about
>>because of timely destruction. My claim is that a closure should close over 
>>the
>>entire lexical stack, and not simply those things it uses statically. Chip
>>claims the opposite, arguing that timely destruction implies that this is
>>absolutely the right thing to do. It's also quicker.
>>  
>>
> I'm going to have to side with Piers on this one. My feeling is that having a
> reference to a closure accessible in memory should keep all the possible
> lexicals it can access in memory as well. That said, I can the compiler
> optimizing memory consumption by destroying all the outer lexicals that it can
> prove will never be used by the inner closure. However, the presence of an
> eval' in the closure makes such a proof tenuous at best.
>
> On the other hand, one could easily view the eval as constructing yet another
> closure, and it's unclear if we wish for that closure to be able to "skip" the
> first level outer closure to directly access the 2nd level outer lexicals. In
> that respect, I could see things Chip's way.
>
> As for the warning, it should only be a warning if strictures are on, for 
> using
> the now undeclared '$x' inside the eval.
>
>>But dammit, I'm doing runtime evaluation of code strings, I don't care about
>>quicker.
>>
>>If it's not the default can it please be mandated that there be some way of
>>doing:
>>
>>    sub foo { my $x = 1; return sub is lexically_greedy {eval $^codestring} }
>>
>>in other words, some way of declaring that a subroutine wants to hang onto
>>every lexical it can see in its lexical stack, not matter what static analysis
>>may say.
>>
>>  
>>
> Well, you could always do something like:
>
>     sub foo { my $x = 1; return sub {my $x := $OUTER::x; eval $^codestring} }
>
> But I'm spending too much time in other languages lately to remember exactly
> how "$OUTER::x" is spelled for certain. One could probably even write a macro
> that auto-binds all the lexicals in the outer scope to the current scope.

Only if I actually know what variables which were within scope when that inner
sub was compiled are going to be used by my passed in code string. I really
don't want to have to write a macro to walk the OUTER:: chain in order to build
a something like:

   sub { my $foo = $OUTER::foo;
         my $bar = $OUTER::OUTER::bar;
         ...;
         eval $^codestring }

Just to pull everything into scope.

And even if I could do that, what I actually want to be able to do is something
like this:

    $continuation.bindings.eval_in_this_scope($^codestring);

Which can be done today in Ruby and which is one of the enabling technologies
for tools like Rails.

Reply via email to