use warnings;
use Class::MOP;
+use namespace::clean 0.08 ();
use Sub::Exporter;
: caller($offset);
}
+my %EXPORT_SPEC;
+sub build_import_methods {
+ my $class = shift;
+ my %args = @_;
+
+ my $exporting_package = caller();
+
+ $EXPORT_SPEC{$exporting_package} = \%args;
+
+ my ( $exporter, $exported )
+ = $class->_build_exporter( exporting_package => $exporting_package,
+ %args );
+
+ my $import = sub {
+ my $caller = Moose::Exporter->get_caller(@_);
+
+ # this works because both pragmas set $^H (see perldoc perlvar)
+ # which affects the current compilation - i.e. the file who use'd
+ # us - which is why we don't need to do anything special to make
+ # it affect that file rather than this one (which is already compiled)
+
+ strict->import;
+ warnings->import;
+
+ # we should never export to main
+ if ( $caller eq 'main' ) {
+ warn
+ qq{$exporting_package does not export its sugar to the 'main' package.\n};
+ return;
+ }
+
+ if ( $exporting_package->can('_init_meta') ) {
+ $exporting_package->_init_meta(
+ for_class => $caller,
+ %{ $args{init_meta_args} || {} }
+ );
+ }
+
+ goto $exporter;
+ };
+
+ # [12:24] <mst> yes. that's horrible. I know. but it should work.
+ #
+ # This will hopefully be replaced in the future once
+ # namespace::clean has an API for it.
+ my $unimport = sub {
+ @_ = ( 'namespace::clean', @{ $exported } );
+
+ goto &namespace::clean::import;
+ };
+
+ no strict 'refs';
+ *{ $exporting_package . '::import' } = $import;
+ *{ $exporting_package . '::unimport' } = $unimport;
+}
+
my %EXPORTED;
-sub build_exporter {
+sub _build_exporter {
my $class = shift;
my %args = @_;
- my $exporting_pkg = caller();
+ my $exporting_package = $args{exporting_package};
+ my @exported_names;
my %exports;
for my $name ( @{ $args{with_caller} } ) {
- my $sub = do { no strict 'refs'; \&{ $exporting_pkg . '::' . $name } };
+ my $sub = do { no strict 'refs'; \&{ $exporting_package . '::' . $name } };
my $wrapped = Class::MOP::subname(
- $exporting_pkg . '::' . $name => sub { $sub->( scalar caller(), @_ ) } );
+ $exporting_package . '::' . $name => sub { $sub->( scalar caller(), @_ ) } );
$exports{$name} = sub { $wrapped };
- push @{ $EXPORTED{$exporting_pkg} }, $name;
+ push @exported_names, $name;
}
for my $name ( @{ $args{as_is} } ) {
$name = ( Class::MOP::get_code_info($name) )[1];
}
else {
- $sub = do { no strict 'refs'; \&{ $exporting_pkg . '::' . $name } };
+ $sub = do { no strict 'refs'; \&{ $exporting_package . '::' . $name } };
- push @{ $EXPORTED{$exporting_pkg} }, $name;
+ push @exported_names, $name;
}
$exports{$name} = sub { $sub };
}
- return Sub::Exporter::build_exporter(
+ my $exporter = Sub::Exporter::build_exporter(
{
exports => \%exports,
groups => { default => [':all'] }
}
);
-}
-
-sub remove_keywords {
- my $class = shift;
- my %args = @_;
-
- no strict 'refs';
-
- for my $name ( @{ $EXPORTED{ $args{source} } } ) {
- if ( defined &{ $args{from} . '::' . $name } ) {
- my $keyword = \&{ $args{from} . '::' . $name };
- # make sure it is from us
- my ($pkg_name) = Class::MOP::get_code_info($keyword);
- next if $pkg_name ne $args{source};
-
- # and if it is from us, then undef the slot
- delete ${ $args{from} . '::' }{$name};
- }
- }
+ return $exporter, \@exported_names;
}
1;