From 636f22f307ff0dc94a2c2ec23d49c872ecddbc02 Mon Sep 17 00:00:00 2001 From: Jesse Luehrs Date: Mon, 19 Jul 2010 19:10:14 -0500 Subject: initial implementation --- lib/MooseX/Exporter/Easy.pm | 72 +++++++++++++++ lib/MooseX/Exporter/Easy/Meta/Role/Package.pm | 128 ++++++++++++++++++++++++++ 2 files changed, 200 insertions(+) create mode 100644 lib/MooseX/Exporter/Easy/Meta/Role/Package.pm (limited to 'lib') 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; -- cgit v1.2.3-54-g00ecf