Beefy Boxes and Bandwidth Generously Provided by pair Networks
"be consistent"

Re: No DESTROY object.

by ambrus (Abbot)
on Jan 22, 2010 at 13:31 UTC ( #818958=note: print w/replies, xml ) Need Help??

in reply to No DESTROY object.

sub {} does not refer to any lexical variables, so it is optimized to always return a reference to the same sub, instead of creating subs every time. Thus, that sub is never destroyed. For example, see that this prints the same address twice.

perl -we 'sub f { sub { } }; $x = f(); $y = f(); warn "$x $y";'

In comparision, if you get a reference with an array or hash constructor [] or {}, or with a lexical variable like do {\my $t} or do {\my @a}, you always get a fresh one because arrays and hashes are mutable.

Update: sorry, originally I posted the wrong example code, the one that shows when the sub does refer to a lexical variable, so the two calls to f returned subs that referred to two different variables, thus, the addresses were different. It's now corrected above, below is that old code.

perl -we 'sub f { my $t; sub { $t } }; $x = f(); $y = f(); warn "$x $y +";'

Replies are listed 'Best First'.
Re^2: No DESTROY object.
by JavaFan (Canon) on Jan 22, 2010 at 14:36 UTC
    That prints two different addresses. But since it's a sub that does refer to a lexical variable, it neither proves, nor disproves your claim about optimization.

    But note this:

    $ perl5.10.1 -we 'sub f { our $t; sub { $t } }; $x = f(); $y = f(); wa +rn "$x $y";' CODE(0x95ca930) CODE(0x95ca930) at -e line 1.
    Same address. But not so in 5.8.9
    $ perl5.8.9 -we 'sub f { our $t; sub { $t } }; $x = f(); $y = f(); war +n "$x $y";' CODE(0x867218c) CODE(0x8672258) at -e line 1.
Re^2: No DESTROY object.
by WizardOfUz (Friar) on Jan 22, 2010 at 14:29 UTC
    For example, see that this prints the same address twice.

    No, it does not, at least not in perl v5.10.0:

    perl -we 'sub f { my $t; sub { $t } }; $x = f(); $y = f(); warn "$x $y +";' CODE(0x82998c4) CODE(0x8299964) at -e line 1.

    Has perl become smarter?

Re^2: No DESTROY object.
by gam3 (Curate) on Jan 22, 2010 at 17:15 UTC
    There are 2 problems with your argument that jump out at me.
    1. first - DESTROY should still get called even if only once.
    2. second sub { $bob } does not get DESTROYed either and it certainly not immutable.
    package Foo; sub print { print "@_\n"; } sub DESTROY { print "@_ DESTROY\n"; } our $bob = "x\n"; my $x = bless(sub {$bob}, 'Foo'); $x->print('$bob'); print $x->(); $bob = "y\n"; print $x->(); $bob = undef; __END__ Foo=CODE(0xe8a278) $bob x y
    -- gam3
    A picture is worth a thousand words, but takes 200K.

      For your second question, if you replace our $bob to my $bob, then the DESTROY does get called. This way, perl knows that $bob is a global so it optimizes the sub constructor to a constant again.

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://818958]
[Corion]: ambrus: AnyEvent(::HTTP) doesn't integrate well with Prima, that's my main problem
[Corion]: There is a weirdo shim because there is a POE integration for Prima, and if you use that, you can use the POE adapter of AnyEvent. What I'd want is something transport agnostic that parses HTTP or produces HTTP output, so that the communication with ...
[Corion]: ... the socket is done by my code. Ideally that module would not be based on callbacks ;)
[Corion]: Basically, something that decouples the HTTP parsing (+ determining whether to redirect, etc) from the IO
[Corion]: All clients I'm aware of don't do that but issue all IO themselves

How do I use this? | Other CB clients
Other Users?
Others about the Monastery: (12)
As of 2016-12-07 15:50 GMT
Find Nodes?
    Voting Booth?
    On a regular basis, I'm most likely to spy upon:

    Results (130 votes). Check out past polls.