develooper Front page | perl.perl5.porters | Postings from December 2015

Re: Proposal: Add {-as => 'new_name'} feature to Exporter.pm

Thread Previous | Thread Next
From:
Chad Granum
Date:
December 18, 2015 03:17
Subject:
Re: Proposal: Add {-as => 'new_name'} feature to Exporter.pm
Message ID:
CAJFr3ksYCT5UFYCyOcteOqYpOaxFLuCsMG9q6703vuS1d0ix2w@mail.gmail.com
From 1957f9e25f435d39a6e9d444db17deeee887f587 Mon Sep 17 00:00:00 2001
From: Chad Granum <exodist7@gmail.com>
Date: Thu, 17 Dec 2015 19:15:23 -0800
Subject: [PATCH] Add renaming capabilities to Exporter.pm

 * Uses the same syntax as newer exporters for consistency.
 * Added tests
 * Added documentation
 * Added another exporter to the list at the end
---
 dist/Exporter/lib/Exporter.pm       | 14 +++++++++++++-
 dist/Exporter/lib/Exporter/Heavy.pm | 23 ++++++++++++++++-------
 dist/Exporter/t/Exporter.t          | 20 +++++++++++++++++++-
 3 files changed, 48 insertions(+), 9 deletions(-)

diff --git a/dist/Exporter/lib/Exporter.pm b/dist/Exporter/lib/Exporter.pm
index 0b3db21..4e94c70 100644
--- a/dist/Exporter/lib/Exporter.pm
+++ b/dist/Exporter/lib/Exporter.pm
@@ -9,7 +9,7 @@ require 5.006;
 our $Debug = 0;
 our $ExportLevel = 0;
 our $Verbose ||= 0;
-our $VERSION = '5.72';
+our $VERSION = '5.73';
 our (%Cache);
 
 sub as_heavy {
@@ -449,6 +449,17 @@ If you are writing a package that C<AUTOLOAD>s, consider forcing
 an C<AUTOLOAD> for any constants explicitly imported by other packages
 or which are usually used when your package is C<use>d.
 
+=head2 RENAMING SYMBOLS ON IMPORT
+
+As of version 5.73 you can rename symbols that you import.
+
+    use Some::Exporter some_sub => { -as => 'new_name' };
+
+    new_name(); # sub 'some_sub' is now present as 'new_name'.
+
+This syntax is consistent with newer exporting tools such as L<Sub::Exporter>
+and L<Exporter::Declare>.
+
 =head1 Good Practices
 
 =head2 Declaring C<@EXPORT_OK> and Friends
@@ -579,6 +590,7 @@ a sample list of such modules.
     Exporter::Tidy
     Sub::Exporter / Sub::Installer
     Perl6::Export / Perl6::Export::Attrs
+    Exporter::Declare
 
 =head1 LICENSE
 
diff --git a/dist/Exporter/lib/Exporter/Heavy.pm b/dist/Exporter/lib/Exporter/Heavy.pm
index 21b67c1..9f48e8b 100644
--- a/dist/Exporter/lib/Exporter/Heavy.pm
+++ b/dist/Exporter/lib/Exporter/Heavy.pm
@@ -145,7 +145,7 @@ sub heavy_export {
 			$cache_is_current = 1;
 		    }
 
-		    if (!$export_cache->{$sym}) {
+ 		    if (!$export_cache->{$sym} && ref($sym) ne 'HASH') {
 			# accumulate the non-exports
 			push @carp,
 			  qq["$sym" is not exported by the $pkg module\n];
@@ -194,13 +194,22 @@ sub heavy_export {
     warn "Importing into $callpkg from $pkg: ",
 		join(", ",sort @imports) if $Exporter::Verbose;
 
-    foreach $sym (@imports) {
-	# shortcut for the common case of no type character
-	(*{"${callpkg}::$sym"} = \&{"${pkg}::$sym"}, next)
-	    unless $sym =~ s/^(\W)//;
-	$type = $1;
+    while (my $sym  = shift @imports) {
+        # First split into sigil and name
+        # We need to take the sigil from the symbol, not the new name where a
+        # sigil is not used.
+        my $type = ($sym =~ s/^(\W)//) ? $1 : '';
+
+        # Update name if an alternative was specified
+        my $spec = (@imports && ref($imports[0]) eq 'HASH') ? shift @imports : undef;
+        my $name = ($spec && $spec->{'-as'}) ? $spec->{'-as'} : $sym;
+
+        # shortcut for the common case of no type character
+        (*{"${callpkg}::$name"} = \&{"${pkg}::$sym"}, next)
+            unless $type;
+
 	no warnings 'once';
-	*{"${callpkg}::$sym"} =
+	*{"${callpkg}::$name"} =
 	    $type eq '&' ? \&{"${pkg}::$sym"} :
 	    $type eq '$' ? \${"${pkg}::$sym"} :
 	    $type eq '@' ? \@{"${pkg}::$sym"} :
diff --git a/dist/Exporter/t/Exporter.t b/dist/Exporter/t/Exporter.t
index d6ac63f..2a30ca8 100644
--- a/dist/Exporter/t/Exporter.t
+++ b/dist/Exporter/t/Exporter.t
@@ -18,7 +18,7 @@ sub ok ($;$) {
 
 BEGIN {
     $test = 1;
-    print "1..31\n";
+    print "1..34\n";
     require Exporter;
     ok( 1, 'Exporter compiled' );
 }
@@ -243,3 +243,21 @@ sub TIESCALAR{bless[]}
  }
 }
 ::ok(1, 'import with tied $_');
+
+package main::TestRename;
+
+BEGIN {
+    $INC{'main/TestRename/Foo.pm'} = 1;
+    package main::TestRename::Foo;
+
+    our @EXPORT = qw/foo/;
+    use base 'Exporter';
+
+    sub foo { 'foo' }
+}
+
+use main::TestRename::Foo 'foo' => {-as => 'bar'};
+
+::ok(__PACKAGE__->can('bar'), "imported foo as bar");
+::ok(!__PACKAGE__->can('foo'), "Did not import 'foo'");
+::ok(bar() eq 'foo', "bar does what we expect");
-- 
1.9.1


Thread Previous | Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About