Why do you want to export symbols to Perl?

It seems odd to me that Perl would allow a package to export symbols to a different package namespace. The exporting package does not know if a package already in use already defines a symbol with the same name, and it certainly cannot guarantee that it is the only package exporting a symbol under that name.

A very common problem caused by this use of CGI and LWP :: Simple at the same time. Both packages export head()

and throw an error. I know it's easy enough to get around, but that's not the point. You won't need to use a job to use the two practically-core Perl libraries.

As far as I can see, the only reason for this is laziness. You save some keystrokes without typing Foo :: or using the object interface, but is it really worth it?

+2


source to share


5 answers


The practice of exporting all functions from a module by default is not recommended for Perl. You should only export functions if you have a good reason. The recommended practice is to use EXPORT_OK

for the user to enter the name of the required function, e.g .:

use My::Module 'my_function';

      



Modules on the other hand, when, like LWP :: Simple and CGI, were written before this recommendation came along and it is now difficult to change them so as not to export things as it would break existing software. I think this recommendation came from people who notice such problems.

In any case, Perl's object-oriented objects, or whatever it calls, doesn't require you to export anything, and you don't need to specify $ foo->, so part of your question is wrong.

+9


source


Export is a feature. Like any other function in any language, it can cause problems if you (ab) use it too often or shouldn't. It's good when used wisely and badly otherwise, like any other function.

On a day when there weren't many modules around, it didn't seem so bad by default. However, with 15,000 packets on the CPAN, conflicts inevitably arise and this is unfortunate. However, patching modules can now break existing code. Whenever you make a bad choice of an interface and publish it to the public, you are committed to it, even if you don't like it.



So it sucks, but the way it is and there are ways around it.

+9


source


The export package does not know if a package that has already been used is already using a symbol with the same name, and certainly cannot guarantee that it is the only package exporting a symbol with that name.

If you'd like, I suppose your routine import()

can check, but the default Exporter.pm routine does not check by default (and probably should not, because it will be used a lot, and always checks, the name is defined will cause serious slowdown ( and if you find a conflict, what is Exporter expected?)).

As far as I can see, the only reason for this is laziness. You save some keystrokes without typing Foo :: or using the object interface, but is it really worth it?

Foo::

not too bad, but consider My::Company::Private::Special::Namespace::

- your code will look much cleaner if we just export a few things. Not everything can (or should) be in the top-level namespace.

The export mechanism should be used when it cleans up the code. When namespaces collide it shouldn't be used as it clearly doesn't make the code cleaner, but otherwise I'm a fan of exporting things on demand.

+6


source


It's not just laziness, and it's not just old modules. Take Moose , the "postmodern object system" and Rose :: DB :: Object , the object interface to the popular ORM. Both import the method meta

into the use

ing package symbol table to expose the functions in this module.

This is no different from the problem of multiple inheritance of modules, each providing a method with the same name, except that the order of your parent will determine which version of that method gets called (or you could define your own overridden version, which is like manually adding the functions of both parents together).

Personally, I would like to combine Rose :: DB :: Object with Moose, but this is not that important to work: you can create a class created by Moose that has a "Rose :: DB :: Object object inside it, not one that "is" (ie inherits from) Rose :: DB :: Object.

+3


source


One of the nicest things about "open source" Perl packages is that if you're not crazy about how the author of the project created something, you can change it.

package LWPS;
require LWP::Simple;

for my $sub (@LWP::Simple::EXPORT, @LWP::Simple::EXPORT_OK) {
    no strict 'refs';
    *$sub = sub {shift; goto &{'LWP::Simple::' . $sub}};
}

package main;

my $page = LWPS->get('http://...');

      

of course, in this case it will LWP::Simple::get()

probably be better.

+3


source







All Articles