That is an interesting case BEGIN { my $x; sub foo { ... $x ... } } Perl could decide to implement that as a closure (and probably does because "BEGIN" blocks are implemented as subroutines). But lets find out:
The "cleaned up" output is:#!/usr/bin/perl -w use strict; use Devel::Peek qw(Dump); BEGIN { my $x; sub begin { ++$x; } } sub justmy { my $x; ++$x; } sub ifmy { my $x if 0; ++$x; } { my $x; sub static { ++$x; } } sub nest { my $x; sub inner { ++$x } } sub gen { my $x; return sub { ++$x }; } *insert= gen(); Dump $_ for( \&begin, \&justmy, \&ifmy, \&static, \&inner, gen(), \&insert + );
or just considerVariable "$x" will not stay shared at closure.pl line 27. begin: SV = RV(0x1a83a20) at 0x1a65068 SV = PVCV(0x1a8340c) at 0x1a62144 GVGV::GV = 0x1a7b6c0 "main" :: "begin" PADLIST = 0x1a7b690 1. 0x1a621b0 (FAKE "$x" 0-57) OUTSIDE = 0x1a620fc (UNIQUE) justmy: SV = RV(0x1a83a2c) at 0x1a65098 SV = PVCV(0x1a8345c) at 0x1a620f0 GVGV::GV = 0x1a7b72c "main" :: "justmy" PADLIST = 0x1a7b708 1. 0x1a7b714 ("$x" 59-60) OUTSIDE = 0x1a6f124 (MAIN) ifmy: SV = RV(0x1a83a30) at 0x1a650b0 SV = PVCV(0x1a7adbc) at 0x1a7b750 GVGV::GV = 0x1a7b798 "main" :: "ifmy" PADLIST = 0x1a7b774 1. 0x1a7b780 ("$x" 61-62) OUTSIDE = 0x1a6f124 (MAIN) static: SV = RV(0x1a839dc) at 0x1a650e0 SV = PVCV(0x1a7ada4) at 0x1a7b76c GVGV::GV = 0x1a7b7a8 "main" :: "static" PADLIST = 0x1a7b790 1. 0x1a620f0 (FAKE "$x" 0-64) OUTSIDE = 0x1a6f124 (MAIN) inner: SV = RV(0x1a83a34) at 0x1a650c8 SV = PVCV(0x1a7ae5c) at 0x1a7b81c GVGV::GV = 0x1a7b858 "main" :: "inner" PADLIST = 0x1a7b840 1. 0x1a7b7ec (FAKE "$x" 0-64) OUTSIDE = 0x1a7b7bc (nest) gen(): SV = RV(0x1a83a38) at 0x1a65158 SV = PVCV(0x1a7af9c) at 0x1a650e0 FLAGS = (ANON,CLONED) GVGV::GV = 0x1a7b924 "main" :: "__ANON__" PADLIST = 0x1a65128 1. 0x1a65080 (FAKE "$x" 0-67) OUTSIDE = 0x1a7b894 (gen) SV = PVCV(0x1a7aeac) at 0x1a7b894 GVGV::GV = 0x1a7b93c "main" :: "gen" PADLIST = 0x1a7b8b8 1. 0x1a65170 ("$x" 66-68) 2. 0x1a7b8e8 ("&" 1--1) OUTSIDE = 0x1a6f124 (MAIN) insert: SV = RV(0x1a83a3c) at 0x1a65188 SV = PVCV(0x1a7af4c) at 0x1a6f01c FLAGS = (ANON,CLONED) GVGV::GV = 0x1a7b924 "main" :: "__ANON__" FLAGS = 0x6 PADLIST = 0x1a6f0f4 1. 0x1a7b8c4 (FAKE "$x" 0-67) OUTSIDE = 0x1a7b894 (gen) SV = PVCV(0x1a7aeac) at 0x1a7b894 GVGV::GV = 0x1a7b93c "main" :: "gen" PADLIST = 0x1a7b8b8 1. 0x1a65170 ("$x" 66-68) 2. 0x1a7b8e8 ("&" 1--1) OUTSIDE = 0x1a6f124 (MAIN)
which seems to indicates that "justmy" and "ifmy" are not implemented as closures but all of the rest are implemented as closures. So I'll certainly be more lenient in what I let other people call closures. (:begin: 1. 0x1a621b0 (FAKE "$x" 0-57) justmy: 1. 0x1a7b714 ("$x" 59-60) ifmy: 1. 0x1a7b780 ("$x" 61-62) static: 1. 0x1a620f0 (FAKE "$x" 0-64) inner: 1. 0x1a7b7ec (FAKE "$x" 0-64) gen(): 1. 0x1a65080 (FAKE "$x" 0-67) insert: 1. 0x1a7b8c4 (FAKE "$x" 0-67)
But it also indicates that the padlist is carried around for ordinary subroutines, which makes that aspect of the implementation less important to me.
I think that the important thing about closures is being able to call the same code but have it use different variables (without passing them in as arguments). Above, only the anonymous subroutine and "insert" meet that criterion. So those are what I'll call closures. The other 3 cases I'll call "static variables that Perl implements via closures" if pushed. :)
- tye (but my friends call me "Tye")In reply to (tye)Re2: A Real Closure
by tye
in thread Unusual Closure Behaviour
by tachyon
For: | Use: | ||
& | & | ||
< | < | ||
> | > | ||
[ | [ | ||
] | ] |