Stories
Slash Boxes
Comments
NOTE: use Perl; is on undef hiatus. You can read content, but you can't post it. More info will be forthcoming forthcomingly.

All the Perl that's Practical to Extract and Report

use Perl Log In

Log In

[ Create a new account ]

Ovid (2709)

Ovid
  (email not shown publicly)
http://publius-ovidius.livejournal.com/
AOL IM: ovidperl (Add Buddy, Send Message)

Stuff with the Perl Foundation. A couple of patches in the Perl core. A few CPAN modules. That about sums it up.

Journal of Ovid (2709)

Wednesday May 09, 2007
12:14 PM

More On Maintaining State with Traits

[ #33232 ]

On my O'Reilly blog, I wrote about problems with maintaining state with traits. The original traits model did not have a provision to handling state and this, I think, is a serious oversight. It's a limitation I've run into several times now and I need to fix it. Fortunately, I've not had a problem because the applications I've written using stateful trait methods have been applications with a very short runtime (such as test suites or small command-line programs), but in a persistent environment, when traits attempt to maintain state, they don't have any clean way of cleaning up when the object goes out of scope.

My thought was to try overriding DESTROY, if present, but this presents a difficult technical problem:

#!/usr/bin/perl -l

use strict;
use warnings;

{
    package Foo;

    sub new { bless {}, shift }

    sub DESTROY {
        use Data::Dumper;
        print Dumper \@_;
    }
}

my $foo = Foo->new;

__END__
# prints
$VAR1 = [
          bless( {}, 'Foo' )
        ];

So if I do that, I get an instance of Foo to play with. However, if I attempt to override:

#!/usr/bin/perl -l

use strict;
use warnings;

{
    package Foo;

    sub new { bless {}, shift }

    sub DESTROY {
        use Data::Dumper;
        print Dumper \@_;
    }
}

my $foo = Foo->new;
my $destroy = *Foo::DESTROY{CODE};
{
    no warnings 'redefine';
    *Foo::DESTROY = sub { print 'boo hoo'; $destroy->($foo) };
}
__END__
# prints
boo hoo
$VAR1 = [
          undef
        ];

Damn. No instance. I don't know that I can override DESTROY safely. The only other thought I can think of is specifying that a user state that they're using a 'stateful' trait and, if the trait is applied at compile or runtime, run the appropriate checks, and in either case, bless the class into an anonymous subclass which has its own DESTROY. That will let me use DESTROY, but "Yuck!"

Update: sheesh. I feel really stupid today. I can fix that with this:

    *Foo::DESTROY = sub { print 'boo hoo'; $destroy->(shift) };

The Fine Print: The following comments are owned by whoever posted them. We are not responsible for them in any way.
 Full
 Abbreviated
 Hidden
More | Login | Reply
Loading... please wait.