Error "Undefined subroutine" & module references

Discussion in 'Perl Misc' started by mailbox@cpacker.org, Aug 10, 2005.

  1. Guest

    Given the program below:

    #!/usr/bin/perl
    use ATrial;
    $D = ATrial::SomeSubr();
    print "|$D|\n";

    I find that if I remove the "ATrial::" from
    the assignment statement, I get a runtime
    error "Undefined subroutine &main::SomeSubr called..."

    According to the "Perl Cookbook," page 446, I should
    be able to dispense with that prefix if I have
    the "use" statement. What's going on?

    The module ATrial.pm is in the same directory,
    and is as follows:

    package ATrial;
    sub SomeSubr () {
    return "HELLO";
    }
    1;

    The really odd thing is that I've been cruising along for
    several hundred lines one directory level up from where
    I am now in a project in which I've created a couple of
    modules and referenced stuff in them from a dozen scripts.
    I don't see any obvious difference in the usage there.
    Using -I with pathnames in the command line to make things
    more explicit has had no effect.
    , Aug 10, 2005
    #1
    1. Advertising

  2. Paul Lalli Guest

    wrote:
    > Given the program below:
    >
    > #!/usr/bin/perl
    > use ATrial;
    > $D = ATrial::SomeSubr();
    > print "|$D|\n";
    >
    > I find that if I remove the "ATrial::" from
    > the assignment statement, I get a runtime
    > error "Undefined subroutine &main::SomeSubr called..."
    >
    > According to the "Perl Cookbook," page 446, I should
    > be able to dispense with that prefix if I have
    > the "use" statement. What's going on?


    I don't have my copy of the Cookbook on me, but I have to believe
    you're misinterpreting what it's telling you.

    You can only call another module's subroutines without fully qualifying
    them if that module exported that subroutine name, and your current
    package imported it. The 'use' statement does import all of ATrial's
    exports. However...

    > The module ATrial.pm is in the same directory,
    > and is as follows:
    >
    > package ATrial;
    > sub SomeSubr () {
    > return "HELLO";
    > }
    > 1;


    We see here that ATrial never exported SomeSubr. In order for this to
    work the way you wanted, you have to add the following lines under
    'package ATrial;' :
    use Exporter;
    our @ISA = qw/Exporter/;
    our @EXPORT = qw/SomeSubr/;

    Alternatively, you can make ATrial simply *offer* to export SomeSubr,
    at which point your main package has to specifically request it. To do
    this, replace the last line above with:
    our @EXPORT_OK = qw/SomeSubr/;
    and change the 'use' statement in the main file to:
    use ATrial qw/SomeSubr/;

    For more information on exporting and importing, please read:
    perldoc Exporter

    Paul Lalli
    Paul Lalli, Aug 10, 2005
    #2
    1. Advertising

  3. Guest

    Paul Lalli wrote:
    > wrote:
    > I don't have my copy of the Cookbook on me, but I have to believe
    > you're misinterpreting what it's telling you.



    You're right. Reading further, I see it shows how to use the lines of
    code you indicated. But that's a lot of stuff, and how did I get this
    far without needing it? I looked at my earlier code and noticed this:
    My key module -- I even call it Reusables.pm -- doesn't have a package
    statement! So going back to the example in my posting, I removed the
    package statement in ATrial.pm, and the program worked without the
    explicit reference "ATrial::". Apparently Perl is giving me some
    undocumented latitude in external referencing, and I can only wonder
    where the boundaries are.
    , Aug 10, 2005
    #3
  4. Paul Lalli Guest

    wrote:
    > Paul Lalli wrote:
    > > wrote:
    > > I don't have my copy of the Cookbook on me, but I have to believe
    > > you're misinterpreting what it's telling you.

    >
    >
    > You're right. Reading further, I see it shows how to use the lines of
    > code you indicated. But that's a lot of stuff, and how did I get this
    > far without needing it? I looked at my earlier code and noticed this:
    > My key module -- I even call it Reusables.pm -- doesn't have a package
    > statement! So going back to the example in my posting, I removed the
    > package statement in ATrial.pm, and the program worked without the
    > explicit reference "ATrial::". Apparently Perl is giving me some
    > undocumented latitude in external referencing, and I can only wonder
    > where the boundaries are.


    Any piece of code that does not have an explicit package statement in
    effect is in package main::. Therefore, when you removed the package
    ATrial; statement, that code in ATrial.pm became part of the main::
    package as well. When you call a subroutine without a fully-qualified
    name (ie, without the package label), it is taken to mean "the current
    package". Since both your main file and ATrial.pm are in the same
    package, the code executes without errors. You would have seen the
    same result if you'd added 'package ATrial;' to your main file, rather
    than removed it from ATrial.pm

    When you 'use Atrial;', you're really doing two distinct things:
    require 'Atrial.pm';
    Atrial->import();

    The first line simply loads the code in Atrial.pm. The second line
    attempt to import from the Atrial class. Nothing about the first line
    says that Atrial.pm has to contain a package named Atrial::. And as
    for the second line, if no such class exists, the import() call is
    silently ignored (I believe via a call to the "empty" core level
    import() function, but I could be wrong on that).

    Check out
    perldoc -f use
    perldoc -f require
    for more information

    Paul Lalli
    Paul Lalli, Aug 10, 2005
    #4
  5. Guest

    Jim Gibson wrote:
    > The default package is "main". So without a package name, any external
    > file included by your program with 'do', 'require', or 'use' becomes
    > part of the main package and may be referenced without a qualifier
    > (unless of course 'use strict' is in effect).


    Yes, I see now...except that my only available reference, "The Perl
    Cookbook," doesn't mention "use" in this context. Thanks to everyone.
    , Aug 10, 2005
    #5
  6. Paul Lalli Guest

    wrote:
    > Jim Gibson wrote:
    > > The default package is "main". So without a package name, any external
    > > file included by your program with 'do', 'require', or 'use' becomes
    > > part of the main package and may be referenced without a qualifier
    > > (unless of course 'use strict' is in effect).

    >
    > Yes, I see now...except that my only available reference, "The Perl
    > Cookbook," doesn't mention "use" in this context. Thanks to everyone.


    1) The Cookbook is not a reference. It is a list of recipees.
    2) The Cookbook is by no means your "only available" reference. You
    obviously have access to the internet. You also obviously have access
    to a Perl distrobution.

    http://search.cpan.org/dist/perl/pod/perlfunc.pod#use
    or from the command line:
    perldoc -f use

    Paul Lalli
    Paul Lalli, Aug 10, 2005
    #6
  7. Guest

    Paul Lalli wrote:
    >
    > http://search.cpan.org/dist/perl/pod/perlfunc.pod#use
    > or from the command line:
    > perldoc -f use


    Well, that Web page -- at least that section of it -- was not written
    for mortals like me; it has no practical value for an applications guy.
    As for perldoc, I get an error message
    No documentation found for "perlfunc".
    Maybe I should talk to our sysadmin about that. Or, I'll just put it on
    my wish list for when we migrate to the new system shortly.
    , Aug 11, 2005
    #7
  8. Paul Lalli Guest

    wrote:
    > Paul Lalli wrote:
    > >
    > > http://search.cpan.org/dist/perl/pod/perlfunc.pod#use
    > > or from the command line:
    > > perldoc -f use

    >
    > Well, that Web page -- at least that section of it -- was not written
    > for mortals like me; it has no practical value for an applications guy.


    I disagree. Perhaps you could let us know what part of that
    documentation is unclear to you, and someone here could clarify it?

    > As for perldoc, I get an error message
    > No documentation found for "perlfunc".
    > Maybe I should talk to our sysadmin about that.


    Yes. Whoever installed perl on your system neglected to install the
    corresponding documentation.

    Paul Lalli
    Paul Lalli, Aug 11, 2005
    #8
  9. Paul Lalli wrote:
    > wrote:
    >> Jim Gibson wrote:
    >>> The default package is "main". So without a package name, any external
    >>> file included by your program with 'do', 'require', or 'use' becomes
    >>> part of the main package and may be referenced without a qualifier
    >>> (unless of course 'use strict' is in effect).

    >>
    >> Yes, I see now...except that my only available reference, "The Perl
    >> Cookbook," doesn't mention "use" in this context. Thanks to everyone.

    >
    > 1) The Cookbook is not a reference. It is a list of recipees.
    > 2) The Cookbook is by no means your "only available" reference. You
    > obviously have access to the internet. You also obviously have access
    > to a Perl distrobution.


    True, but isn't it rather unusual to use() a file with Perl code that is
    not a module?

    --
    Gunnar Hjalmarsson
    Email: http://www.gunnar.cc/cgi-bin/contact.pl
    Gunnar Hjalmarsson, Aug 11, 2005
    #9
  10. Paul Lalli Guest

    Gunnar Hjalmarsson wrote:
    > Paul Lalli wrote:
    > > 1) The Cookbook is not a reference. It is a list of recipees.
    > > 2) The Cookbook is by no means your "only available" reference. You
    > > obviously have access to the internet. You also obviously have access
    > > to a Perl distrobution.

    >
    > True, but isn't it rather unusual to use() a file with Perl code that is
    > not a module?


    I don't know. I don't think I've ever included code from an external
    file that wasn't a module. I guess maybe I'd do a simple 'require'
    instead? But 'use' on a file that doesn't define a module (and
    therefore does not have an associated import() method) is really just
    BEGIN { require '...' } anyway, so I'm not sure I see how it would
    hurt.

    Paul Lalli
    Paul Lalli, Aug 11, 2005
    #10
  11. Paul Lalli wrote:
    > Gunnar Hjalmarsson wrote:
    >> Paul Lalli wrote:
    >>> 1) The Cookbook is not a reference. It is a list of recipees.
    >>> 2) The Cookbook is by no means your "only available" reference. You
    >>> obviously have access to the internet. You also obviously have access
    >>> to a Perl distrobution.

    >>
    >> True, but isn't it rather unusual to use() a file with Perl code that is
    >> not a module?

    >
    > I don't know. ... I'm not sure I see how it would hurt.


    I didn't intend to imply that it might hurt, but the absence in the
    cookbook of use() in the context of including non-module files of Perl
    code might be non-accidental. ;-)

    --
    Gunnar Hjalmarsson
    Email: http://www.gunnar.cc/cgi-bin/contact.pl
    Gunnar Hjalmarsson, Aug 11, 2005
    #11
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Mark
    Replies:
    0
    Views:
    484
  2. Replies:
    4
    Views:
    182
    Bob Walton
    Aug 12, 2003
  3. Torsten Mangner

    testing for 'undefined subroutine'

    Torsten Mangner, Nov 4, 2003, in forum: Perl Misc
    Replies:
    3
    Views:
    142
    Bob Walton
    Nov 5, 2003
  4. Moulin Kluge
    Replies:
    2
    Views:
    340
    pkent
    Jan 27, 2004
  5. it_says_BALLS_on_your forehead
    Replies:
    0
    Views:
    352
    it_says_BALLS_on_your forehead
    Jan 24, 2006
Loading...

Share This Page