Lexically importing useful features into a large script

Sometimes I need a useful utility function, for example List::Util::max in the middle of a large program that does a lot of things. So if i do

 use List::Util 'max'; 

At the top of my program, I am stuck with this symbol, polluting my entire namespace, although I only need it in one subroutine.

So, I was thinking of trying another template:

 use List::Util (); # a whole bunch of stuff later... sub blah { List::Util->import( 'max' ); $blah = max @foobar; ... } 

There are two problems with this. Firstly, it will not automatically unimport at the end of the block (drat.) I would have to undo everything using unimport .

Another problem is that the prototypes do not seem to apply correctly, so I have to say max( @foobar ) instead of a more beautiful version without letters.

Is there an easy way to temporarily import characters for a block that will automatically delete them at the end of the block and that will also handle prototypes correctly?

+6
import perl lexical-scope
source share
4 answers

You can localize a character table entry:

 use List::Util (); @y = qw(1 3 5 -9 4); sub max { # return maximum *absolute value* of list my $max = abs(shift); $max<abs($_) && ($max=$abs($_)) for @_; return $max; } sub max2 { local *max = *List::Util::max; return max(@_); } print "My max: ", max(@y), "\n"; # ==> 9 print "List::Util::max ", max2(@y), "\n"; # ==> 5 
+1
source share

Just do it, it is much better and cleaner:

 package Foo; use strict; use warnings; use List::Util 'max'; use namespace::autoclean; # your method definitions here... 

namespace :: autoclean will be "unimport" after the symbol for completing the package compilation cycle. A call to it in your method will work, but you have no pollution of the namespace (the *Foo::max symbol has been deleted), and the call to $obj->max() will fail.

Alternatively, you can take a look at Lexical :: Import (I don't know anything about this, the irc bird mentioned this).

+4
source share

If you use only max in one routine, I would not import it into the namespace at all. My decision -

 use List::Util; sub blah { print List::Util::max(@list); } 
+2
source share

perlfunc implies that no MODULE should do what you want:

 sub blah { use List::Util qw(max); say max @foobar; no List::Util; } 

but this does not work - at least not for List :: Util. I believe that he will need to define a unimport method. Even then, I'm not sure if you had a bare max in your module that calls different definitions.

+1
source share

All Articles