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

I have "use strict" turned on and require the packages I use. I am making a call to a package function, e.g. my $dummyvar = mypackage::myfunc("hello");

At runtime I get an error suggesting that I may need to predeclare mypackage::myfunc. Yet neither the Llama nor the Camel books list "predeclaration" in their indexes.

My question is, what is predeclaration with respect to the use of package functions? When should I use it?

I had previously thought that matters which are not covered in the Llama and Camel books were not matters which initiate monks such as myself needed to be concerned with and were not necessary for Perl enlightenment. Could I have been wrong?

Replies are listed 'Best First'.
Re (tilly) 1: Junior Monk Predeclaration Question
by tilly (Archbishop) on Aug 28, 2000 at 23:51 UTC
    You can predeclare with "use subs", by importing the function from a module with use (not require), or you can avoid the error message by using the form &mypackage::myfunc("hello");
Re: Junior Monk Predeclaration Question
by tye (Sage) on Aug 29, 2000 at 00:24 UTC

    I think you skipped an important bit of information. What error are you getting? The suggestions to prepend "&" will probably eliminate the error message, but may be like adding a typecast in C: it silences the complaint but doesn't fix the underlying problem. This solution should only be used when you fully understand the error message and have determined that the message is reporting a "false positive", that is, something that is often an error but isn't an error in this specific case. ar0n's answer sounds more likely to truely fix things.

    The only reason I can think that you want to predeclare a sub in that context is that it has a prototype. Using & will just silence Perl and ignore the prototype. The correct fix is probably to make sure the declaration (or a predeclaration) of the function has been compiled before the call to that function is compiled.

    As ar0n mentioned, require takes place at run time, so any function declarations in the required file won't be seen before the requiring script is compiled. Changing the "require" to "use" will cause the used file to be parse right after the "use" statement is compiled. It will also cause the "import" routine, if any, of the used module to be invoked right after that.

    There are a lot of details possible here. But I think that most of them still lead to "use" being the correct way to fix it. Give us more details if you have doubts.

    And predeclaration of functions look like this:

    sub myfunc; sub mypackage::myfunc; sub mypackage::myfunc(); sub mypackage::myfunc(\%);
    where the prototype (if any) should match the prototype (if any) used in the definition of the function.

            - tye (but my friends call me "Tye")
Re: Junior Monk Predeclaration Question
by cwest (Friar) on Aug 28, 2000 at 23:53 UTC
    You may need to call your function like so:
    &mypackage::myfunc("hello");
    since that function hasn't been defined in your code, it may require the leading `&'.

    Also, myfunc() probably doesn't autoload for you, helping to cause this problem.

    check out the docs for Shell for a similar example.

    use Shell; sub ls; print ls;
    without 'sub ls;', this would fail under strict.
    --
    Casey
    
Re: Junior Monk Predeclaration Question
by ar0n (Priest) on Aug 28, 2000 at 23:51 UTC
    A mildly educated guess would be that require isn't compile time, hence you'll need to prototype your subs. I think if you'd use use, your problem would go away, since all the packages get compiled right away.

    -- ar0n

Re: Junior Monk Predeclaration Question
by Anonymous Monk on Aug 29, 2000 at 01:06 UTC
    Thanks everybody!! I chose the "use subs" solution and the problem went away.