http://qs1969.pair.com?node_id=594133

palette has asked for the wisdom of the Perl Monks concerning the following question:

Can anyone tell whether it is valid code
one.pm
package one; @ISA = qw(Exporter); @EXPORT = qw(method1); sub method1 { print "method1 greets hello"; } 1;

two.pl
use one; print "its here"; method1; print "here";

While trying to execute two.pl I am able to see only the following output "It's herehere". Why is the print statement inside the function method1 not displayed. Please correct me if there is any mistake.



It must be something really simple.

Replies are listed 'Best First'.
Re: Issue with Exporter
by imp (Priest) on Jan 11, 2007 at 13:20 UTC
    The synopsis for Exporter says:
    package YourModule;
    require Exporter;
    @ISA = qw(Exporter);
    
    You omitted the 'require Exporter'.

    I prefer this version personally:

    package one; use strict; use warnings; use base qw(Exporter); our @EXPORT = qw(method1); sub method1 { print "method1\n"; } 1;
Re: Issue with Exporter
by davorg (Chancellor) on Jan 11, 2007 at 13:18 UTC
    Can anyone tell whether it is valid code

    Oh, it's completely valid code. It just doesn't do what you want it to :-)

    You need to add

    require Exporter;

    to one.pm.

    It's all very well setting up the @EXPORT variable, but you need to load the Exporter code in order for it to make any difference.

    --
    <http://dave.org.uk>

    "The first rule of Perl club is you do not talk about Perl club."
    -- Chip Salzenberg

Re: Issue with Exporter
by ferreira (Chaplain) on Jan 11, 2007 at 13:23 UTC

    Don't forget to say

    use strict; use warnings;
    at the beginning of your modules and scripts, unless you have a very good reason not to do it.

    Probably, method1 from one.pm is not getting called, but instead a stub that does nothing -- this is a "goodness" of not using strict (a promiscuous way to being too forgiven with unresolved symbols).

    You will realize that if use strict; use warnings; were added, this will work as you expect, printing "its heremethod1 greets hellohere". But it is not right yet. The remaining issue is that to tell a package is inheriting the exporter capabilities from Exporter, you need

    require Exporter; our @ISA = qw(Exporter); our @EXPORT = qw(method1);

    The require statement will load Exporter.pm for you. (And our will be need if you're "strict".) Why does it work only inserting use strict; use warnings; in two.pl? Because some of these load Exporter and it becomes accessible as a side effect to the remaining of the script. This is not a thing to rely on. So I suggest you do the right thing: being strict, calling for warnings, requiring what you need. This will work always, not sometimes.

      It works. Thankyou. I shud adhere to the rules of being strict and use warnings.

      I would like to know why it is not working with use and working with require. Anyway use is require and import together right.

      Thanks

        It works for me with use Exporter; instead of require Exporter;. The point is that use'ing is not necessary when what you want is to inherit from Exporter in package one.

Re: Issue with Exporter
by almut (Canon) on Jan 11, 2007 at 14:57 UTC

    For the sake of completeness, yet another approach would be to directly import Exporter's import method into the namespace of your module. In that case it doesn't need to be looked up via inheritance, so you don't need to setup @ISA or use base ...

    In other words, from the following 3 options, you can choose whichever you like best:

    package One; use strict; use warnings; # --- option 1 - inheritance via @ISA # require Exporter; # our @ISA = qw(Exporter); # --- # --- option 2 - inheritance via use base ... # use base "Exporter"; # --- # --- option 3 - directly import Exporter's import() use Exporter "import"; # --- # ( @EXPORT or @EXPORT_OK always needed ) our @EXPORT = qw(method1); sub method1 { print "method1 greets hello"; } 1;

    (Also, note that I changed the package name to "One" (capitalized). AFAIK, lowercase module names are - by convention - reserved for pragmatic modules like use strict;, use integer;, etc.)

    BTW, a slight peculiarity with use strict; use warnings; in this particular case is that it does not (and cannot) warn you about potential problems due to not loading Exporter yourself (because, as ferreira pointed out, Exporter already is being loaded as a side effect of using strictures). For this reason, it could be argued that options 2 or 3 are the ones to prefer, as they do not share this potential pitfall...

      I tried the code with the 3rd option mentioned. Its working fine when I am using @EXPORT but when I am using
      our @EXPORT_OK = qw(method1);

      Its not working and the output I am getting is "its herehere"

      Thanks

        Do you understand the difference between @EXPORT and @EXPORT_OK?

        Symbols mentioned in @EXPORT are automatically exported by your module. Symbols mentioned in @EXPORT_OK are made available for export, they are not automatically exported. to export symbols that are in @EXPORT_OK, you need to explicitly name them in the "use" statement for the module.

        --
        <http://dave.org.uk>

        "The first rule of Perl club is you do not talk about Perl club."
        -- Chip Salzenberg

        @EXPORT hold the symbols that are exported by default when you don't mention explicitly any symbols.

        use one; # will import the symbols in @EXPORT

        while @EXPORT_OK hold the symbols that can be exported on demand.

        use one qw(m1 m2); # m1 and m2 should be in @EXPORT or @EXPORT_OK

        Read more about it in the Exporter documentation.

        Hi,

        I just forgot to include the name of the method in the use statement.

        Thankyou very much.
Re: Issue with Exporter
by Fletch (Bishop) on Jan 11, 2007 at 14:52 UTC

    And a minor style nit that I don't think has been mentioned yet:

    Lowercase module names are reserved by convention for use as compiler directives ("pragmas") by Perl (e.g. strict, warnings, sort). Granted this was probably just a name you came up with off the cuff for testing, but it's better to get in the habit of capitalizing your package names. It's akin to not using $a and $b as variable names even in one-off code; sometime down the road you're going to wind up spending a couple of hours chasing down a "bug" that isn't.

Re: Issue with Exporter
by Samy_rio (Vicar) on Jan 11, 2007 at 13:09 UTC

    Hi palette, below code will help you,

    use one qw(method1); print "its here"; method1; print "here";

    Untested

    Here is explanation Exporter

    Thanks davorg++.

    Regards,
    Velusamy R.


    eval"print uc\"\\c$_\""for split'','j)@,/6%@0%2,`e@3!-9v2)/@|6%,53!-9@2~j';

      Untested

      Perhaps you should have tested it :-)

      @EXPORT controls symbols which are automatically exported from the module. If a symbol is included in @EXPORT then you don't need to explicitly name it in the use command. You only need to explicitly name symbols that are in the @EXPORT_OK array.

      The actual problem is that the module doesn't load Exporter.pm - so putting symbols in @EXPORT has no effect.

      --
      <http://dave.org.uk>

      "The first rule of Perl club is you do not talk about Perl club."
      -- Chip Salzenberg