Skip to content

Instantly share code, notes, and snippets.

@BenGoldberg1
Last active December 27, 2015 06:49
Show Gist options
  • Save BenGoldberg1/7284889 to your computer and use it in GitHub Desktop.
Save BenGoldberg1/7284889 to your computer and use it in GitHub Desktop.
Defines an alternative boilerplate for class methods.
#!perl
package Alias::Shift;
require Devel::LexAlias;
use strict;
use warnings;
my $skip;
sub shifter {
my ( $pack, $ref, @attr ) = @_;
if ( my @bad = grep $_ ne 'shift', @attr ) {
return @bad;
}
unless ( defined $skip ) {
$skip = 0;
++$skip while caller($skip) ne 'attributes';
++$skip;
}
{ package DB; caller($skip); }
unless (@DB::args) {
require Carp;
Carp::croak('Cannot shift from @_, when @_ is empty!');
}
my $val = CORE::shift(@DB::args);
Devel::LexAlias::alias_r( $val, $ref );
}
no warnings 'once';
*MODIFY_HASH_ATTRIBUTES = \&shifter;
*MODIFY_ARRAY_ATTRIBUTES = \&shifter;
*MODIFY_SCALAR_ATTRIBUTES = \&shifter;
1;
__END__
Quick Example Usage:
package MyPack;
use parent qw(Alias::Shift);
sub new {
my ($class, %args) = @_;
bless \%args, $class;
}
sub foo {
my %self : shift;
++$self{bar};
}
1;
__END__
Basically, this is an alternative to doing:
sub foo {
my $self = shift;
++$self->{bar};
}
It saves some typing (if you ignore the use parent ...) and
makes your code look a little bit cleaner. Obviously it's
not nearly as fast as normal code, since shifter gets called
at runtime for every lexical with the :shift attribute, but
if someone with better knowledge of perl's internals were to
take a whack at it, it ought to be possible to write:
sub foo : shift(%self) {
++$self{bar};
}
The attribute would modify the subroutine (at compile time),
to insert code into &foo, eqivilant to alias_r( \(my %self), shift ).
Even cooler, imho, would be something like:
use Attribute::CPPish;
sub foo :CPPish (%self $bar) {
++$bar;
}
Which would create lexicals for %self and $bar, where %self
is gotten by shifting @_, and $bar is a lexical which is aliased
to $self{bar}.
But that's very much beyond my coding skills.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment