Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FAQ 7.12: What's a closure? #826

Closed
p5pRT opened this issue Nov 7, 1999 · 4 comments
Closed

FAQ 7.12: What's a closure? #826

p5pRT opened this issue Nov 7, 1999 · 4 comments

Comments

@p5pRT
Copy link

p5pRT commented Nov 7, 1999

Migrated from rt.perl.org#1754 (status was 'resolved')

Searchable as RT1754$

@p5pRT
Copy link
Author

p5pRT commented Nov 7, 1999

From ilya@math.ohio-state.edu

$foo = 1; $^W = 1;
sub test1 {my $foo = 2; return sub { eval shift } }
print test1()->('$foo');

P.S. See the *scope* where eval '' is executed? This *scope* has a
lexical $foo inherited from the enclosing lexical scope. Thus
the call test1()->('$foo') will return this lexical $foo.

 However\, since the "subsubroutine" of test1 is not a closure\, it
 does not \*preserve\* the reference to this $foo\.  Hence the
 refcount of $foo decreases when test1 returns\, which effectively
 makes $foo stale=undefined\.

 Putting $foo into the subsubroutine will make it a closure\, thus
 $foo will be 108 during the call\.

Thank you for the explanation of what happens. I now understand how it
is that test1's return value returns undef -- someone else had
explained it, but I think your explanation is clearer. I still think
test1 *should* return something different. But that's a topic for p5p.

This cannot be done. But I Cc perlbug​:

Here is what *can* be done. When evalling, internal (sub {}) scope
does not contain $foo. So the search for $foo continues up-scope.
Scope of test1 is tested, and $foo is found there.

POSSIBLE ENHANCEMENT​: given that the lexical was found inside eval '',
that the compilation of test1 is completed already, and that test1 is
not active any more, give a warning

  Access to stale lexical of enclosing scope from eval ''

[Variant​: additionally to testing that test1 is not active, test that
"the `active' position inside test1" is in the scope of $foo.]

Ilya

@p5pRT
Copy link
Author

p5pRT commented Aug 7, 2002

From @gbarr

This is still present in 5.8.0

@p5pRT
Copy link
Author

p5pRT commented Jun 24, 2003

From @iabyn

(Just reviewing old Perl bug reports)

The current development version of Perl (which will eventually be
released as 5.10.0) contains a number of lexical/closure fixes
and enhancements, which among other things, now cause this original
test code​:

  $foo = 1; $^W = 1;
  sub test1 {my $foo = 2; return sub { eval shift } }
  print test1()->('$foo');

to emit the run-time warning​:

  Variable "$foo" is not available at (eval 1) line 2.

since at the time of the eval, the lexical $foo is not active.
Note that it does *not* instead use the value of the global $foo.

(This warning is the equivalent of the 'stale' warning that Ilya
originally suggested).

I am therefore making this report a resolved.

Regards,

Dave M.

@p5pRT
Copy link
Author

p5pRT commented Jun 24, 2003

@iabyn - Status changed from 'open' to 'resolved'

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant