List Info

Thread: So bewilderingly. about closure




So bewilderingly. about closure
user name
2007-09-20 04:32:18
C:>cat ttt.pl
use strict;
use warnings;

{
  my $x = 'A';
  sub f { sub { $x++ }       }
  sub g { sub { $x++ } if $x }
}

my $F=f();
my $G=g();

print $F->(),$G->(),"," for 1..4;
print "n";

C:>ttt.pl
0A,1B,2C,3D,

C:>

Re: So bewilderingly. about closure
user name
2007-09-20 04:48:15
On 9/20/07, flw <su2admingmail.com> wrote:
> C:>cat ttt.pl
> use strict;
> use warnings;
>
> {
>   my $x = 'A';
>   sub f { sub { $x++ }       }
>   sub g { sub { $x++ } if $x }
> }
>
> my $F=f();
> my $G=g();
>
> print $F->(),$G->(),"," for 1..4;
> print "n";
>
> C:>ttt.pl
> 0A,1B,2C,3D,
>
> C:>

Known bug in closure implementation. Since sub f doesnt
mention $x the
sub that it returns doesnt enclose the same $x as the sub
returned by
g().

Changing the code to read

{
    my $x = 'A';
    sub f { sub { print $x; $x++ }       }
    sub g { sub { print $x; $x++ } if $x }
}

Produces:

SCALAR(0x225f18)
SCALAR(0x226d4c)
0A,
SCALAR(0x225f18)
SCALAR(0x226d4c)
1B,
SCALAR(0x225f18)
SCALAR(0x226d4c)
2C,
SCALAR(0x225f18)
SCALAR(0x226d4c)
3D,

Which shows that the two are operating on different scalars.
I had
guessed that the f() sub would be operating on $: but
it turns out
that it isnt. Somehow *two* $x'es are being created. Which i
find
surprising even though i know about this bug.

The solution is to add a dummy line to f() to make sure that
 it mentions $x.

{
    my $x = 'A';
    sub f { my $y=$x; sub { print $x; $x++ }       }
    sub g {           sub { print $x; $x++ } if $x }
}


Will cause both subs to bind to the same scalar.


Cheers,
Yves


-- 
perl -Mre=debug -e "/just|another|perl|hacker/"

Re: So bewilderingly. about closure
user name
2007-09-20 07:32:43
On Thu, Sep 20, 2007 at 11:48:15AM +0200, demerphq wrote:
> On 9/20/07, flw <su2admingmail.com> wrote:
> > C:>cat ttt.pl
> > use strict;
> > use warnings;
> >
> > {
> >   my $x = 'A';
> >   sub f { sub { $x++ }       }
> >   sub g { sub { $x++ } if $x }
> > }
> >
> > my $F=f();
> > my $G=g();
> >
> > print $F->(),$G->(),"," for 1..4;
> > print "n";
> >
> > C:>ttt.pl
> > 0A,1B,2C,3D,
> >
> > C:>
> 
> Known bug in closure implementation.

which is fixed in 5.9.0 onwards/

-- 
Gravity is just a theory; teach Intelligent Falling in our
schools!
    http://www
.theonion.com/content/node/39512

Re: So bewilderingly. about closure
user name
2007-09-20 13:39:33
On 9/20/07, demerphq <demerphqgmail.com> wrote:
> The solution is to add a dummy line to f() to make sure
that  it mentions $x.
>
> {
>     my $x = 'A';
>     sub f { my $y=$x; sub { print $x; $x++ }       }
>     sub g {           sub { print $x; $x++ } if $x }
> }

My experience was just a void context mention was enough. No
operation
was required:

sub f { $x; sub { ... } }

Josh

Re: So bewilderingly. about closure
user name
2007-09-20 15:01:49
Removed perl-qa from the cc list, since it's not really on
topic.

On Thu, September 20, 2007 11:39 am, Joshua ben Jore wrote:
> On 9/20/07, demerphq <demerphqgmail.com> wrote:
>
>> The solution is to add a dummy line to f() to make
sure that  it
>> mentions $x.
>>
>> {
>> my $x = 'A'; sub f { my $y=$x; sub { print $x;
$x++ }       } sub g {
>> sub { print $x; $x++ } if $x } }
>>
>
> My experience was just a void context mention was
enough. No operation
> was required:
>
> sub f { $x; sub { ... } }

To avoid the warning:

sub f { $x if 0; sub { ... } }



Re: So bewilderingly. about closure
user name
2007-09-20 20:59:02
Thank demerphq and other guys.

[1-6]

about | contact  Other archives ( Real Estate discussion Medical topics )