Stories
Slash Boxes
Comments
NOTE: use Perl; is on undef hiatus. You can read content, but you can't post it. More info will be forthcoming forthcomingly.

All the Perl that's Practical to Extract and Report

The Fine Print: The following comments are owned by whoever posted them. We are not responsible for them in any way.
 Full
 Abbreviated
 Hidden
More | Login | Reply
Loading... please wait.
  • The reason for not discussing that is that generally, you shouldn't mix exported functions and methods. That's because a method really expects to be called with an object as its first argument, which is less likely to happen correctly if you say method($obj) instead of $obj->method(). Also, you don't get inheritance because you're not going through method dispatch.

    I'm sure there are a few cases where you might want to export things, but generally, I'd think twice before pulling in Exporter.

    -Dom

    • You lost me. I understand the $obj->method thing, but what I didn't understand and had hoped Dave would get into was the whole Exporter thing. What is it, why is it used, etc...

      Some objects are written such that when you use them, you have to import the methods you'll be using, like:

      use My::Module qw/ method1 method2 /;

      And others are written so you can just say:

      use My::Module;

      And then you automatically have access to the methods.

      Jason
      • I think you're getting confused between ordinary functions and OO code (methods). If you don't call it with an arrow, it's not a method, it's a function (with the annoying exception of the indirect method call syntax, but don't worry about that yet).

        When you use a module, you're actually using OO behind the scenes, even though the results aren't usually OO. What happens is that Perl ends up calling the import() method of the named class and passing it the list that you have supplied.

        What makes it a method is that internally it gets called as My::Module->import('method1','method2');. Because of the arrow, the thing to the left (the class name here) gets put in as the first argument to the import() subroutine. Because it's a class name rather than an object, this type of method is usually known as a class method.

        Now chances are that you haven't defined an import() method in your module. But if you've followed the docs, you've got something like this:

        require Exporter;
        @My::Module::ISA = qw( Exporter );
        @My::Module::EXPORT_OK = qw( method1 method2 );

        So, when you say use My::Module qw/ method1 method2 /;, you end up calling the import method in your module. Except that it's been set up like a class so that it inherits from the Exporter module. And that's where it finds the import() method. And Exporter::import() knows where to find the list of things to export because it's been given the class name as the first argument. And then it goes away and makes aliases for the subroutines requested in the place that originally said use My::Module ... from.

        So, Exporter is an OO module. And because of that, it means that yours is too because of the inheritance. But, that's probably where it stops.

        If you write your subs in an OO fashion, then they expect to be called as $obj->method(). Because $obj knows what class it's in, you don't need to import those methods into your namespace. This is why I said above that it's generally a bad idea to mix the two.

        Finally, the difference between your first and second example is just a different usage of the Exporter module. If you say @EXPORT = qw( foo bar ), then foo() and bar() will be automatically exported from your module. Whereas if you say @EXPORT_OK = qw( foo bar ); then you have to explicitly request that foo() and bar() be imported by naming them on the use line. This is generally considered to be better design since it doesn't fill your namespace with crap, the way that the POSIX module does.

        One tip to note: Even if a module exports stuff by default, you can ask it export nothing by saying use My::Module ().