May 2010 Archives

a less magical with block.

| | Comments (0)
For some reason lately there has been interest in re-creating the Javascript with function in Perl (despite the fact that ES5 Strict removes with and with has problems of its own).  These seem to be focused on using code-rewriting solutions (Source filters and Devel::Declare), which use too much magic for too little syntactical gain, why not something like the following:

package WithBlock;
use strict;
use warnings;
use Scalar::Util 'blessed';
use Exporter qw{import};
our @EXPORT = qw{with dowith};
sub with($&) {
        no strict 'refs';
        my $pkg = caller(0);
        my ($scope, $sub) = @_;
        my $class = blessed $scope || $scope;
        my @withsubs;
        local *{"${pkg}::AUTOLOAD"} = sub {
                our $AUTOLOAD;
                my ($method) = ($AUTOLOAD =~ m{.+::(.+)$}g);
                if (my $isub = $scope->can($method)) {
                        push @withsubs, $AUTOLOAD;
                        *{$AUTOLOAD} = sub {
                                unshift @_, $scope;
                                goto &$isub;
                        };
                        goto &{$AUTOLOAD};
                }
                die "Undefined subroutine &$AUTOLOAD called"
        };
        $sub->();
        foreach my $sub (@withsubs) {
                undef *{$sub};
       }
}

sub dowith(&$) {
        @_[0, 1] = @_[1, 0];
        goto __PACKAGE__->can('with');
}

Admittedly you don't get the 'nice' syntax of with ($object) { code block } you have to settle for with $object, sub { code block } or dowith { code block } $object.  WithBlock only works for functions of $object that aren't already defined in your current scope.



About this Archive

This page is an archive of entries from May 2010 listed from newest to oldest.

August 2009 is the previous archive.

June 2010 is the next archive.

Find recent content on the main index or look in the archives to find all content.

Categories

Pages