From: Shawn M Moore Date: Mon, 4 Aug 2008 01:34:26 +0000 (+0000) Subject: Add a remove_keywords function so if you extend Moose you don't have to cargo cult... X-Git-Tag: 0_55_01~60 X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=ce265cc3f4a94886a67dbc0f48ef5d2bfde5a965;p=gitmo%2FMoose.git Add a remove_keywords function so if you extend Moose you don't have to cargo cult Moose's unimport --- diff --git a/Changes b/Changes index afb63a4..175298b 100644 --- a/Changes +++ b/Changes @@ -1,5 +1,11 @@ Revision history for Perl extension Moose +0.56 + * Moose + * Moose::Cookbook::Extending::Recipe2 + - Add a remove_keywords function so if you extend Moose + you don't have to cargo cult Moose's unimport (Sartak) + 0.55 Sun August 3, 2008 * Moose::Meta::Attribute - breaking down the way 'handles' methods are diff --git a/lib/Moose.pm b/lib/Moose.pm index 5fba49e..9551c07 100644 --- a/lib/Moose.pm +++ b/lib/Moose.pm @@ -190,26 +190,40 @@ use Moose::Util (); } sub unimport { - no strict 'refs'; my $class = _get_caller(@_); - # loop through the exports ... - foreach my $name ( keys %exports ) { + remove_keywords( + source => __PACKAGE__, + package => $class, + keywords => [ keys %exports ], + ); + } - # if we find one ... - if ( defined &{ $class . '::' . $name } ) { - my $keyword = \&{ $class . '::' . $name }; +} - # make sure it is from Moose - my ($pkg_name) = Class::MOP::get_code_info($keyword); - next if $pkg_name ne 'Moose'; +sub remove_keywords { + my ( %args ) = @_; - # and if it is from Moose then undef the slot - delete ${ $class . '::' }{$name}; - } + my $source = $args{source}; + my $package = $args{package}; + + no strict 'refs'; + + # loop through the keywords ... + foreach my $name ( @{ $args{keywords} } ) { + + # if we find one ... + if ( defined &{ $package . '::' . $name } ) { + my $keyword = \&{ $package . '::' . $name }; + + # make sure it is from us + my ($pkg_name) = Class::MOP::get_code_info($keyword); + next if $pkg_name ne $source; + + # and if it is from us, then undef the slot + delete ${ $package . '::' }{$name}; } } - } sub init_meta { @@ -818,6 +832,19 @@ and optionally a baseclass and a metaclass as arguments. For more detail on this topic, see L. +=head2 B + +The remove_keywords method is called by Moose's C to remove Moose's +keywords from a package when C is used. If you extend Moose with +new keywords, you should provide an C that calls C +to remove your sugar. + +C takes named parameters C (to make sure that we +don't remove keywords defined by somebody else), C (from which we're +removing keywords), and C (an array reference of keyword names). + +For more detail on this topic, see L. + =head1 CAVEATS =over 4 diff --git a/lib/Moose/Cookbook/Extending/Recipe2.pod b/lib/Moose/Cookbook/Extending/Recipe2.pod index 80dbfff..e565e45 100644 --- a/lib/Moose/Cookbook/Extending/Recipe2.pod +++ b/lib/Moose/Cookbook/Extending/Recipe2.pod @@ -36,18 +36,11 @@ Moose::Cookbook::Extending::Recipe2 - Acting like Moose.pm and providing sugar M sub unimport { my $caller = caller(); - no strict 'refs'; - foreach my $name (@EXPORT) { - if ( defined &{ $caller . '::' . $name } ) { - my $keyword = \&{ $caller . '::' . $name }; - - my ($pkg_name) = Class::MOP::get_code_info($keyword); - - next if $pkg_name ne __PACKAGE__; - - delete ${ $caller . '::' }{$name}; - } - } + Moose::remove_keywords( + source => __PACKAGE__, + package => $caller, + keywords => \@EXPORT, + ); Moose::unimport( { into_level => 1 } ); } @@ -129,9 +122,11 @@ This is all a bit fragile since it doesn't stack terribly well. You can basically only have one Moose-alike module. This may be fixed in the still-notional C module someday. -The C subroutine is basically a copy of the C -from C. You can copy this verbatim into your code. Again, -this doesn't stack well. +The C subroutine calls the C function +from Moose. This function removes only the keywords exported by +this module. More precisely, C removes from the +C package the keywords given by the C argument +that were created in the C package. Finally, we have our C subroutine. This provides a bit of sugar that looks a lot like C.