Update: A possible valid use for this is in the case of a module which overuses the @EXPORT array, and you don't want to import everything it exports, so you require the module, and use this Importer module to import only the things you want. Another update: No, then you'd just include the symbols you want in the import list of the 'use' statement when you use a module. So I'm still looking for a valid use for this :-)
package Importer; sub import { shift; for (@_) { if (/^([\$@&%]?)(?:\w+::)*(\w+)$/) { ($sigil, $name) = ($1, $2); $var = $sigil ? "\\$_" : "*$_"; eval "*" . caller() . "::$name = $var"; die $@ if $@; } else { die "Can't import $_" } } } 1; # Example use strict; use warnings; use Importer qw($MyPackage::var); # Pretend you have a module/package "MyPackage" that # contains a package variable "var" $MyPackage::var = 5; print "$var\n"; # Update: Alternate version which avoids string eval package Importer; my %sig = ( '$' => sub { *{"$_[0]::$_[1]"} = \${$_[2]} }, '@' => sub { *{"$_[0]::$_[1]"} = \@{$_[2]} }, '%' => sub { *{"$_[0]::$_[1]"} = \%{$_[2]} }, '&' => sub { *{"$_[0]::$_[1]"} = \&{$_[2]} }, '*' => sub { *{"$_[0]::$_[1]"} = *{$_[2]} }, ); # Yet another update: Or maybe you like this better: my %sig = map { $_ => eval sprintf 'sub { *{"$_[0]::$_[1]"} = %s{$_[2]} }', ($_ eq "*") ? $_ : "\\$_" } qw($ @ % & *); sub import { shift; for (@_) { if (/^([\$@&%*]?)((?:\w+::)*(\w+))$/) { ($sigil, $name, $base) = ($1 || "*", $2, $3); $sig{$sigil}->(scalar(caller), $base, $name); } else { die "Can't import $_\n" } } } 1;
|
|---|