Beefy Boxes and Bandwidth Generously Provided by pair Networks
laziness, impatience, and hubris

Namespace Pollution

by Tanalis (Curate)
on May 05, 2003 at 17:48 UTC ( #255687=perlmeditation: print w/replies, xml ) Need Help??


I'm fairly sure this is something that comes up fairly regularly; however, I think as with Perl, people's tastes with regard to it change fairly regularly as well.

A couple of nodes (fairly) recently have looked at the namespace issue from both sides, from an implementation point of view, but nothing as yet has come up regarding the more theoretical side, which is what I'm interested in here.

My original impression, from reading a number of previous posts here, and from looking through the Camel and Black Book, was that automatically importing subroutines, variables and other symbols from a module to user-code was considered a Bad Thing, something to be avoided.

Having said that, though, I can see that it can, on occasion, be a very useful thing if, for example, importing a module exports a set of common subroutines, or secondary modules, to the user's namespace, saving a user of the module from having to figure out exactly which methods or modules in the suite he actually needs.

Going from one extreme to the other, though, it's also (in my opinion) a very nice thing to be able to call, for example, Date::Calc with a string of simply the subs you actually want to use. For larger, more complex modules, I can't help but think that it makes more sense to import what's needed rather than everything that's available.

I think that my personal preference/solution when I'm both writing and using module code is to have an option of either: if the module is used without arguments, or with an :all flag, a "default" set of subs is exported, but if a list of specific subs is given, only those are imported into the module user's namespace. This, I think, gives maximum flexibility for larger apps, and for future expandability of both the module and for the code using that module.

I'm interested to know what others think of this: is there a set "right or wrong" with regard to something like this? I tend to strive to not export anything I don't specifically need: do people think this the best way to go?

Any comments and opinions are welcome :)

-- Foxcub
A friend is someone who can see straight through you, yet still enjoy the view. (Anon)

Replies are listed 'Best First'.
Re: Namespace Pollution
by vladb (Vicar) on May 05, 2003 at 19:42 UTC
    Answering your question whether it is right or wrong to import ':all' methods into client code, I think it depends. I like importing all methods for simple modules and in cases where I am absolutely sure no conflicts would arise. Examples of a few such modules are Date::Manip and Data::Dumper.

    One way to avoid having to deal with the namespace pollution issue in your code, you might try to make use of an OO interface to your modules. Unfortunately not all have one implemented for them, in which case you might resort to selectively importing only the most often used methods, leaving the rest outside of your namespace ;)

    # Under Construction
Re: Namespace Pollution
by BUU (Prior) on May 05, 2003 at 22:33 UTC
    In short, I never (well, except for a few accidents) import anything into my namespace. I always simply do 'require myModule;'. If it's an OO module, well I neither lose nor gain. If it's a non OO module, then I have absolutely no namespace pollution while still being able to use all the features of the module. In specific I call every method as fully qualified, MyModule::foo(); as I feel this allows me to keep track of where the various functions I'm using are.

      1. If the module in question inherits its import() subroutine from the you are right you do not lose anything. If on the other hand the module has its own import(), you may get a nasty surprise. The module may expect it's import() to be called.

      2. While MyModule::foo(); doesn't sound too bad, but imagine you'd have to prepend each and every constant with the package name:

      my $Array = Win32::OLE::Variant->new(VT_ARRAY|VT_R8, [1,2], 2); vs. my $Array = Win32::OLE::Variant->new(Win32::OLE::Variant::VT_ARRAY|Win +32::OLE::Variant::VT_R8, [1,2], 2);
      I think you are exagerating. Also ... keep in mind that the more text you write, the more likely it is that you make a mistake. It's more likely to mistype Win32::FileOp::Delete(... than Delete(....

      Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live.
         -- Rick Osborne

      Edit by castaway: Closed small tag in signature

Re: Namespace Pollution
by Necos (Friar) on May 06, 2003 at 22:52 UTC
    I personally feel that the user of a module should be able to choose whether or not to import functions into their namespace. What if someone writes a function called 32_bit_shift(), and I don't know about it, so I write a function with the same name. Which one gets called (I don't even know, because I try to pick names that won't be used)? Does perl generate an error? I've been lucky enough not to be bitten by conflicting function names.

    I guess no importing is one of the reasons to use OO. Then, even if you have conflicting function names, Perl takes care of which to call (you did bless your objects properly, didn't you?). The one thing that urks me is the libwin32 series of modules export a ton of constants without even asking me. It's a good thing that all of those constants are the same across modules (and consistently valued too), or there would be tons of problems. It's also a good thing that those constants are documented, or someone might create a constant that happens to step on another constant's feet. I think that's one thing you forgot to mention: documentation. A module user should be able to import what they want, and not be forced to take anything he (or she) doesn't want or need. I think it's nicer that way.

    Theodore Charles III
    Network Administrator
    Los Angeles Senior High
    perl -e "map{print++$_}split//,Mdbnr;"
      $ perl -we'sub x { &foo } sub x { &bar }' Subroutine x redefined at -e line 1.
      You won't get a heads-up for multiple imports to the same symbol name, though.

      Makeshifts last the longest.

Log In?

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlmeditation [id://255687]
Approved by sschneid
Front-paged by mattriff
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others scrutinizing the Monastery: (8)
As of 2022-12-06 14:03 GMT
Find Nodes?
    Voting Booth?

    No recent polls found