Chinaxing
Chinaxing

Reputation: 8874

Perl variable garbage collection and refcount

I have a little confuse about the variable garbage collection in Perl in following example :

#!/bin/env perl
use v5.14;

package MyTestModule {
sub foo {
    my $fh = shift;
    for(1..100){
        say "PUT";
        $fh->autoflush(1);
        print $fh "Heloo\n";
        sleep 1;
    }
}
}


package main;

use AnyEvent;
use AnyEvent::Fork::Template;

my $cv = AnyEvent->condvar;
$AnyEvent::Fork::Template->fork->run("MyTestModule::foo", sub {
    my $fh_fh_fh = shift;
    my $w_w_w;
    $w_w_w = AnyEvent->io(fh => $fh_fh_fh, poll => "r", cb => sub {
           $w_w_w unless 1;
           sysread $fh_fh_fh, my $rslt, 10;
           say "GOT:", $rslt;
            }
        );
   });
$cv->wait;

In above code, if I remove the $w_w_w, then because of the AnyEvent->io create a object, its reference become zero, then it will be reclaimed by Perl, which make the code not work ( the cb will not be called );

...
$AnyEvent::Fork::Template->fork->run("MyTestModule::foo", sub {
    my $fh_fh_fh = shift;

    AnyEvent->io(fh => $fh_fh_fh, poll => "r", cb => sub {

           sysread $fh_fh_fh, my $rslt, 10;
            say "GOT:", $rslt;
             }
        );
   });
...

then I assign it to scalar $w_w_w, but I dose not need the $w_w_w in the callback. but the following code not working(callback will not be called):

$AnyEvent::Fork::Template->fork->run("MyTestModule::foo", sub {
    my $fh_fh_fh = shift;
    my $w_w_w;
    $w_w_w = AnyEvent->io(fh => $fh_fh_fh, poll => "r", cb => sub {

       sysread $fh_fh_fh, my $rslt, 10;
            say "GOT:", $rslt;
        }
    );
  });

so I add one line code in the callback(just you can see it in the front of this requestion) :

$w_w_w unless 1;

because the assertion will always be false, so it will not ran, I think the perl compiler/interpreter will optimize this line code ( drop it ), then the $w_w_w 's reference count will be zero. and the callback will not be called also. but it works. so I hope someone can explain this .(the following is a dump of Perl -ODeparse

perl -MO=Deparse t2.pl

sub BEGIN {
    require v5.14;
}
package MyTestModule;
sub foo {
    use strict;
    no feature;
    use feature ':5.12';
    my $fh = shift();
    foreach $_ (1 .. 100) {
        say 'PUT';
        $fh->autoflush(1);
        print $fh "Heloo\n";
        sleep 1;
    }
}
package main;
use strict;
no feature;
use feature ':5.12';
{;};
use AnyEvent;
use AnyEvent::Fork::Template;
my $cv = 'AnyEvent'->condvar;
$AnyEvent::Fork::Template->fork->run('MyTestModule::foo', sub {
    my $fh_fh_fh = shift();
    my $w_w_w;
    $w_w_w = 'AnyEvent'->io('fh', $fh_fh_fh, 'poll', 'r', 'cb', sub {
        '???';
        sysread $fh_fh_fh, my $rslt, 10;
        say 'GOT:', $rslt;
    }
    );
}
);
$cv->wait;

Upvotes: 3

Views: 201

Answers (1)

Chinaxing
Chinaxing

Reputation: 8874

I found the answer in perlmonks.org : http://perlmonks.org/?node_id=1047188

Upvotes: 1

Related Questions