Tuesday 31 May 2011

Perl needs another compile/run cycle hook

In my ongoing interest in Moose I see that you can make a class, thus;

use Moose;
has attr => (is => 'rw', isa => 'Str');
1;

and having made a class, you can make it be much faster by inlining a lot of the things that Moose makes, by declaring that the class is immutable:

__PACKAGE__->meta->make_immutable;

You can also use
namespace::autoclean
to remove the sugar that Moose provides so that your users can't call the sugar as useless methods. This is all a bit ugly, so I wanted a way to hide these in something you put at the top of your code, together, a bit like this:

package MooseX::autoclean;
use Check::UnitCheck;
sub import {
    my $caller = caller();
    Check::UnitCheck::unitcheckify(sub {
 "$importer"->meta->make_immutable;
 });
}    

which would push a UNITCHECK block into my caller's UNITCHECK queue and have it be executed once the caller's code was compiled.

This does not work, of course (in fact sometimes it segfaults, which is a whole different problem), because the caller (the Moose class you are declaring as you do this) has only been compiled by Perl at UNITCHECK stage. The compiled unit has not yet been executed to generate the class. Some other means is required to cause a block of code to be executed once your importing unit has finished executing, this might require the addition of another hook to Perl (er, UNITEND, I suppose) or some other tomfoolery.

No comments:

Post a Comment