Skip to content

Instantly share code, notes, and snippets.

@tobyink
Created October 21, 2012 09:09
Show Gist options
  • Save tobyink/3926451 to your computer and use it in GitHub Desktop.
Save tobyink/3926451 to your computer and use it in GitHub Desktop.
As per Hercynium's suggestion...
use strict;
use warnings;
BEGIN {
package Acme::Constructor::Pythonic;
no thanks;
use Data::OptList qw(mkopt);
use Sub::Install qw(install_sub);
use Module::Runtime qw(use_module);
sub import {
shift;
my $caller = caller;
for my $arg (@{ mkopt(\@_) })
{
my ($class, $opts) = @$arg;
$opts->{class} = $class unless defined $opts->{class};
$opts->{constructor} = 'new' unless defined $opts->{constructor};
$opts->{alias} = $class unless defined $opts->{alias};
if ($opts->{alias} =~ /::(\w+)$/) {
$opts->{alias} = $1;
}
install_sub {
into => $caller,
as => $opts->{alias},
code => sub {
use_module($opts->{class}) unless $opts->{no_require};
my $method = $opts->{class}->can($opts->{constructor});
unshift @_, $opts->{class};
goto $method;
}
}
}
}
}
# Simple example
#
use Acme::Constructor::Pythonic qw( LWP::UserAgent HTTP::Request );
my $req = Request(GET => 'http://www.example.com/');
my $ua = UserAgent();
my $res = $ua->request($req);
print $res->message, "\n";
# More complex example
#
{
package Foo;
sub create { bless [], shift };
sub method { return "OK" };
}
use Acme::Constructor::Pythonic
Foo => { no_require => 1, constructor => 'create', alias => 'Bar' };
my $foo = Bar();
print $foo->method, "\n";
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment