http://qs1969.pair.com?node_id=818972


in reply to No DESTROY object.

This would work as intended:

use strict; use warnings; package Foo; sub new { my $class = shift; return bless( eval 'sub { print "Hello!\n" }', $class ); } sub DESTROY { print "DESTROYing $_[0]\n"; return; } package main; my $object = Foo->new; print "Created $object\n"; $object->(); undef $object; print "Done.\n";
# Created Foo=CODE(0x82cafec) # Hello! # DESTROYing Foo=CODE(0x82cafec) # Done.

Or use closures:

sub new { my $class = shift; my $string = "Hello!\n"; return bless( sub { print $string }, $class ); }

Replies are listed 'Best First'.
Re^2: No DESTROY object.
by gam3 (Curate) on Jan 22, 2010 at 16:16 UTC
    UPDATE: Nevermind.

    An easier fix is

    bless(\sub {}, 'Foo');
    I don't want to fix the problem, I only want to understand it.
    -- gam3
    A picture is worth a thousand words, but takes 200K.

      Errr ... no, it is not:

      perl -we 'bless( \sub {}, "Foo" )->();' Not a CODE reference at -e line 1.
      Because:
      perl -we 'print bless( \sub {}, "Foo" ) . "\n";' Foo=REF(0x82998c4)

      Update: To answer your question: What seems to be happening is that perl inlines the subroutine. See:

      use strict; use warnings; package Foo; sub new { my $class = shift; return bless( sub { print "Hello\n" }, $class ); } sub DESTROY { print "DESTROYing $_[0]\n"; return; } package main; my $object = Foo->new; print "Created $object\n"; undef $object; print "Ha! Ha! Still there!\n"; { no strict 'refs'; my $symbol_table = \%{'Foo::'}; delete $symbol_table->{'new'}; } print "Done.\n";
      # Created Foo=CODE(0x82b682c) # Ha! Ha! Still there! # DESTROYing Foo=CODE(0x82b682c) # Done.
        Great answer. Thanks.
        -- gam3
        A picture is worth a thousand words, but takes 200K.