From: Matt S Trout Date: Sun, 6 May 2012 20:18:25 +0000 (+0000) Subject: explain the method stuff as well X-Git-Tag: v1.000003~2 X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=aa5ad642a4febbccf2639a0a64eb61ba057b9c5d;p=p5sagit%2FImport-Into.git explain the method stuff as well --- diff --git a/Changes b/Changes index 3bdeeba..9e36404 100644 --- a/Changes +++ b/Changes @@ -1,3 +1,7 @@ + - clarify how the method name trick works since apparently now people + understand the eval/import trick they've noticed that that isn't the + only bit of crazy + 1.000002 - 2012-05-05 - improve explanation and add more examples to the SYNOPSIS diff --git a/lib/Import/Into.pm b/lib/Import/Into.pm index 4f3255c..0886ad8 100644 --- a/lib/Import/Into.pm +++ b/lib/Import/Into.pm @@ -56,6 +56,14 @@ Notably, this works: Thing1->import::into(scalar caller); } +Note 2: You do B need to do anything to Thing1 to be able to call +C on it. This is a global method, and is callable on any +package (and in fact on any object as well, although it's rarer that you'd +want to do that). + +If how and why this all works is of interest to you, please read on to the +description immediately below. + =head1 DESCRIPTION Writing exporters is a pain. Some use L, some use L, @@ -111,16 +119,43 @@ effect, and from the right package for caller checking to work - and so behaves correctly for all types of exporter, for pragmas, and for hybrids. Remembering all this, however, is excessively irritating. So I wrote a module -so I didn't have to anymore. Loading L will create a method -C which you can call on a package to import it into another +so I didn't have to anymore. Loading L creates a global method +C which you can call on any package to import it into another package. So now you can simply write: use Import::Into; $thing->import::into($target, @import_args); -Just make sure you already loaded C<$thing> - if you're receiving this from -a parameter, I recommend using L: +This works because of how perl resolves method calls - a call to a simple +method name is resolved against the package of the class or object, so + + $thing->method_name(@args); + +is roughly equivalent to: + + my $code_ref = $thing->can('method_name'); + $code_ref->($thing, @args); + +while if a C<::> is found, the lookup is made relative to the package name +(i.e. everything before the last C<::>) so + + $thing->Package::Name::method_name(@args); + +is roughly equivalent to: + + my $code_ref = Package::Name->can('method_name'); + $code_ref->($thing, @args); + +So since L defines a method C in package C +the syntax reliably calls that. + +For more craziness of this order, have a look at the article I wrote at +L which covers +coderef abuse and the C<${\...}> syntax. + +Final note: You do still need to ensure that you already loaded C<$thing> - if +you're receiving this from a parameter, I recommend using L: use Import::Into; use Module::Runtime qw(use_module); @@ -139,7 +174,7 @@ None yet - maybe this software is perfect! (ahahahahahahahahaha) =head1 COPYRIGHT -Copyright (c) 2010-2011 the Import::Into L and L +Copyright (c) 2012 the Import::Into L and L as listed above. =head1 LICENSE