The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.

Exports

Export routines from a package with names specified by caller of the package.

Synopsis

 use Math::Zap::Vector vector=>'v', units=>'u';

 my $x = v(1,0,0);
 my $y = u();

Rather than:

 my $x = Math::Zap::Vector::vector(1,0,0);
 my $y = Math::Zap::Vector::units();

Description

Export routines from a package with names specified by caller of the package. The routines to be exported are defined in the exporting package as:

 use exports qw(
   vector ($$$)
   units  ()
 );

A suitable sub import() is created, allowing the caller to specify:

 use Math::Zap::Vector vector=>'v', units=>'u';

The caller may then refer to Math::Zap::Vector::vector() as v() and Math::Zap::Vector::units() as u().

The first routine exported is always imported by its export name unless a new name is supplied. Thus:

 use Math::Zap::Vector;

and

 use Math::Zap::Vector vector=>'vector';

have identical effects.

The advantage of this is approach is that it allows the importing package to control the names of the exported routines in its name space rather than the developer of the exporting package, a facility I have not been able to discover in the standard Perl Exporter.pm.

PhilipRBrenan@yahoo.com, 2004, Perl licence

Method: Exports

Construct import routine.

 ##1
 package exports;
 
 #______________________________________________________________________
 # Import for exports: export from exporting package.
 #______________________________________________________________________
 
 sub import(@)
  {shift @_;               # Remove 'exports'
   scalar(@_) % 2 and      # Check number of parameters is even
     die "use exports: Odd number of parameters";
   my $q = join(' ', @_);  # Stringify parameters
   my $p = (caller())[0];  # Exporting package
   my $s =                 # Push data into space of exporting package 
 '@'.$p.'::EXPORTS = qw('.$q.');';
   eval $s; die $@ if $@;  # Perform push and check it worked
 # print "AAAA ", join(' ', @zzz::EXPORTS), "\n"; # Print pushed data
 
 #______________________________________________________________________
 # Construct import routine for exporting package.
 #______________________________________________________________________
 
   $s  = 'pack'."age $p;\n". <<'END'; # Switch to exporting package
 sub import(@)
  {shift @_;
   my @p = ($EXPORTS[0], $EXPORTS[0], @_);
   scalar(@p) % 2 and die "Odd number of parameters";
 
 # Edit parameters and convert to hash
   s/^-// for(@p);
   my %p = @p;
 
 # Switch to package requesting exported methods
   my $c = __PACKAGE__;    # Save exporting package
   my $s =                 # Switch to importing package   
 'pack'.'age '.(caller())[0].";\n".
 'no warnings \'redefine\';'."\n";
 
 # Export valid methods
   my %e = @EXPORTS;
   for my $p(keys(%p))
    {defined $e{$p} or
       die "use $c: Bad method: $p requested.\nValid methods are ".
           join(', ', sort(keys(%e))). "\n";
     $s .= 'sub '.$p{$p}.$e{$p}.' {&'.$c.'::'.$p.'(@_)}'."\n";
    }
 
 # Back to exporting package
   $s .= 'use warnings \'redefine\';'."\n".
         'pack'.'age '.$c.";\n";
 
 # Push exports
 # print "BBBB $s\n";
   eval($s); die $@ if $@;
  }
 END
 
 #______________________________________________________________________
 # Push import routine  
 #______________________________________________________________________
 
 # print "CCCC $s\n";
   eval($s); die $@ if $@;
  }
 
 ##2
 #______________________________________________________________________
 # Package installed successfully
 #______________________________________________________________________
 
 1;