summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorJesse Luehrs <doy@tozt.net>2010-07-19 19:10:14 -0500
committerJesse Luehrs <doy@tozt.net>2010-07-19 19:10:14 -0500
commit636f22f307ff0dc94a2c2ec23d49c872ecddbc02 (patch)
treedab6dc4bc564c61d6a1ace5727238574cfd5ce2b /lib
parentbdd9773b60d3cf2cceea43b4aa1dacd9ed5d492b (diff)
downloadmoosex-exporter-easy-636f22f307ff0dc94a2c2ec23d49c872ecddbc02.tar.gz
moosex-exporter-easy-636f22f307ff0dc94a2c2ec23d49c872ecddbc02.zip
initial implementation
Diffstat (limited to 'lib')
-rw-r--r--lib/MooseX/Exporter/Easy.pm72
-rw-r--r--lib/MooseX/Exporter/Easy/Meta/Role/Package.pm128
2 files changed, 200 insertions, 0 deletions
diff --git a/lib/MooseX/Exporter/Easy.pm b/lib/MooseX/Exporter/Easy.pm
index e69de29..f6d4d5b 100644
--- a/lib/MooseX/Exporter/Easy.pm
+++ b/lib/MooseX/Exporter/Easy.pm
@@ -0,0 +1,72 @@
+package MooseX::Exporter::Easy;
+use Moose ();
+use Moose::Exporter;
+
+use Carp qw(confess);
+use Scalar::Util qw(blessed);
+
+Moose::Exporter->setup_import_methods(
+ with_meta => [qw(with_meta as_is also
+ class_metaroles role_metaroles base_class_roles
+ export)],
+);
+
+sub with_meta {
+ my ($meta, $name, $sub) = @_;
+ confess "with_meta requires a name and a sub to export"
+ unless defined($name) && defined($sub) && ref($sub) eq 'CODE';
+ $meta->add_with_meta($name, $sub);
+}
+
+sub as_is {
+ my ($meta, $name, $sub) = @_;
+ confess "as_is requires a name and a sub to export"
+ unless defined($name) && defined($sub) && ref($sub) eq 'CODE';
+ $meta->add_as_is($name, $sub);
+}
+
+sub also {
+ my ($meta, @also) = @_;
+ $meta->add_also(@also);
+}
+
+sub class_metaroles {
+ my ($meta, $roles) = @_;
+ $meta->class_metaroles($roles);
+}
+
+sub role_metaroles {
+ my ($meta, $roles) = @_;
+ $meta->role_metaroles($roles);
+}
+
+sub base_class_roles {
+ my ($meta, @roles) = @_;
+ $meta->add_base_class_roles(@roles);
+}
+
+sub export {
+ my ($meta) = @_;
+ $meta->setup_exporter;
+}
+
+# move this into Moose::Util?
+sub with_traits {
+ my ($class, @roles) = @_;
+ return Moose::Meta::Class->create_anon_class(
+ superclasses => [$class],
+ roles => \@roles,
+ cache => 1,
+ )->name;
+}
+
+sub init_meta {
+ my $package = shift;
+ my %opts = @_;
+ my $meta_name = blessed(Class::MOP::class_of($opts{for_class}))
+ || 'Class::MOP::Package';
+ $meta_name = with_traits($meta_name, 'MooseX::Exporter::Easy::Meta::Role::Package');
+ my $meta = $meta_name->reinitialize($opts{for_class});
+}
+
+1;
diff --git a/lib/MooseX/Exporter/Easy/Meta/Role/Package.pm b/lib/MooseX/Exporter/Easy/Meta/Role/Package.pm
new file mode 100644
index 0000000..755b50a
--- /dev/null
+++ b/lib/MooseX/Exporter/Easy/Meta/Role/Package.pm
@@ -0,0 +1,128 @@
+package MooseX::Exporter::Easy::Meta::Role::Package;
+use Moose::Role;
+
+has with_meta => (
+ traits => ['Array'],
+ isa => 'ArrayRef[Str]',
+ default => sub { [] },
+ handles => {
+ with_meta => 'elements',
+ _add_with_meta => 'push',
+ }
+);
+
+sub add_with_meta {
+ my $self = shift;
+ my ($name, $sub) = @_;
+ $self->add_package_symbol('&' . $name, $sub);
+ $self->_add_with_meta($name);
+}
+
+has as_is => (
+ traits => ['Array'],
+ isa => 'ArrayRef[Str]',
+ default => sub { [] },
+ handles => {
+ as_is => 'elements',
+ _add_as_is => 'push',
+ }
+);
+
+sub add_as_is {
+ my $self = shift;
+ my ($name, $sub) = @_;
+ $self->add_package_symbol('&' . $name, $sub);
+ $self->_add_as_is($name);
+}
+
+has also => (
+ traits => ['Array'],
+ isa => 'ArrayRef[Str]',
+ default => sub { [] },
+ handles => {
+ also => 'elements',
+ add_also => 'push',
+ }
+);
+
+has class_metaroles => (
+ is => 'rw',
+ isa => 'HashRef[ArrayRef[Str]]',
+ predicate => 'has_class_metaroles',
+);
+
+has role_metaroles => (
+ is => 'rw',
+ isa => 'HashRef[ArrayRef[Str]]',
+ predicate => 'has_role_metaroles',
+);
+
+has base_class_roles => (
+ traits => ['Array'],
+ isa => 'ArrayRef[Str]',
+ default => sub { [] },
+ handles => {
+ base_class_roles => 'elements',
+ add_base_class_roles => 'push',
+ has_base_class_roles => 'count',
+ }
+);
+
+sub setup_exporter {
+ my $self = shift;;
+
+ my ($import, $unimport, $init_meta) = Moose::Exporter->build_import_methods(
+ exporting_package => $self->name,
+ with_meta => [$self->with_meta],
+ as_is => [$self->as_is],
+ also => [$self->also],
+ $self->has_class_metaroles
+ ? (class_metaroles => $self->class_metaroles)
+ : (),
+ $self->has_role_metaroles
+ ? (role_metaroles => $self->role_metaroles)
+ : (),
+ $self->has_base_class_roles
+ ? (base_class_roles => [$self->base_class_roles])
+ : (),
+ );
+
+ $self->add_package_symbol('&import' =>
+ ($self->has_package_symbol('&import_extra')
+ ? sub {
+ my ($package, @args) = @_;
+ $package->import_extra(@args);
+ goto $import;
+ }
+ : $import)
+ );
+ $self->add_package_symbol('&unimport' =>
+ ($self->has_package_symbol('&unimport_extra')
+ ? sub {
+ my ($package, @args) = @_;
+ $package->unimport_extra(@args);
+ goto $unimport;
+ }
+ : $unimport)
+ );
+ if ($init_meta) {
+ $self->add_package_symbol('&init_meta' =>
+ ($self->has_package_symbol('&init_meta_extra')
+ ? sub {
+ my ($package, @args) = @_;
+ $package->init_meta_extra(@args);
+ goto $init_meta;
+ }
+ : $init_meta)
+ );
+ }
+ elsif ($self->has_package_symbol('&init_meta_extra')) {
+ $self->add_package_symbol('&init_meta' =>
+ sub { goto $_[0]->can('init_meta_extra') }
+ );
+ }
+}
+
+no Moose::Role;
+
+1;