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.



Leave a comment

About this Entry

This page contains a single entry by jamesw published on May 16, 2010 11:34 PM.

Grammars in Perl 5.10 was the previous entry in this blog.

alas poor http://search.cpan.org/uploads.rdf is the next entry in this blog.

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

Categories

Pages