package Acme::Constructor::Pythonic;

use 5.006;
use strict;
use warnings;

BEGIN {
	$Acme::Constructor::Pythonic::AUTHORITY = 'cpan:TOBYINK';
	$Acme::Constructor::Pythonic::VERSION   = '0.001';
}

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 ($module, $opts) = @$arg;
		$opts->{class}       = $module unless defined $opts->{class};
		$opts->{constructor} = 'new'   unless defined $opts->{constructor};
		$opts->{alias}       = $module unless defined $opts->{alias};
		
		if (!ref $opts->{alias} and $opts->{alias} =~ /::(\w+)$/) {
			$opts->{alias} = $1;
		}
		
		install_sub
		{
			into => $caller,
			as   => $opts->{alias},
			code => sub {
				use_module($module) unless $opts->{no_require};
				my $method = $opts->{class}->can($opts->{constructor});
				unshift @_, $opts->{class};
				goto $method;
			}
		}
	}
}

1;

__END__

=head1 NAME

Acme::Constructor::Pythonic - import Python-style constructor functions

=head1 SYNOPSIS

    use Acme::Constructor::Pythonic qw(
        LWP::UserAgent
        JSON
        HTTP::Request
    );
    
    my $json = JSON();
    my $ua   = UserAgent();
    my $req  = Request( GET => 'http://www.example.com/foo.json' );
    
    my $data = $json->decode( $ua->request($req)->content )

=head1 DESCRIPTION

In Python you import classes like this:

    import BankAccount from banking

And you instantiate them with something looking like a function call:

    acct = BankAccount(9.99)

This module allows Python-like object instantiation in Perl. The example in
the SYNOPSIS creates three functions C<UserAgent>, C<JSON> and <Request> each
of which just pass through their arguments to the real object constructors.

=head2 Options

Each argument to the Acme::Constructor::Pythonic is a Perl module name and
may be followed by a hashref of options:

    use Acme::Constructor::Pythonic
        'A::Module',
        'Another::Module' => \%some_options,
        'Yes::Another::Module',
    ;

=over

=item *

B<class>

The class to call the constructor on. This is normally the same as the module
name, and that's the default assumption, so there's no usually much point in
providing it.

=item *

B<constructor>

The method name for the constructor. The default is C<new> which is usually
correct.

=item *

B<alias>

The name of the function you want created for you. The default is the last
component of the module name, which is often sensible.

=item *

B<no_require>

Acme::Constructor::Python will automatically load the module specified. Not
straight away; it waits until you actually perform an instantiation. If you
don't want Acme::Constructor::Python to load the module, then set this option
to true.

=back

=head1 BUGS

Please report any bugs to
L<http://rt.cpan.org/Dist/Display.html?Queue=Acme-Constructor-Pythonic>.

=head1 SEE ALSO

L<aliased>.

=head1 AUTHOR

Toby Inkster E<lt>tobyink@cpan.orgE<gt>.

(Though it was SSCAFFIDI's idea.)

=head1 COPYRIGHT AND LICENCE

This software is copyright (c) 2012 by Toby Inkster.

This is free software; you can redistribute it and/or modify it under
the same terms as the Perl 5 programming language system itself.

=head1 DISCLAIMER OF WARRANTIES

THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.

