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

I have a strange question involving modules, subroutine prototypes, and hard references. I am running this under NT. Perl version is ActivePerl build 620 (5.6.0). When I define a subroutine in my script as such:
sub DoSomething( $\$\$ )
and then call it as
my $name; my $path; my $count; DoSomething( $name, \$path, \$count );
everything works fine. So good so far. But, if I move the DoSomething subroutine into a module such as
package MyModule; require Exporter; @ISA = qw( Exporter ); @EXPORT = qw( DoSomething ); sub DoSomething( $\$\$ )
then I get the following error:
Type of arg 2 to MyModule::DoSomething must be scalar (not single ref +constructor) at D:\dlkusters\vsstools\ss2Sink.pl line 56, near "$path + )" Type of arg 3 to MyModule::DoSomething must be scalar (not single ref +constructor) at D:\dlkusters\vsstools\ss2Sink.pl line 56, near "$coun +t )" Execution of D:\dlkusters\vsstools\ss2Sink.pl aborted due to compilati +on errors.
Why does the prototype work in the same script but fail the moment I put it in a module? BTW, if I change the prototype in the module subroutine to
sub DoSomething( $$$ )
then everything works again. This is not my preferred solution since I'm avoiding using prototypes correctly. Thanks, Dave

Replies are listed 'Best First'.
(tye)Re: Modules, Prototypes, and References
by tye (Sage) on Feb 01, 2001 at 23:21 UTC

    In the first case (without making a module), it sounds like the prototype does not appear in the source code before the call(s) to the subroutine. This prevents the prototype from having any effect on those calls and explains why your incorrect calls (given the prototype) are not being flagged as incorrect.

    A "\$" in a sub prototype means that the caller is supposed to type $var and Perl converts that to have the same effect as if the caller had typed \$var. The caller typing \$var would cause a compile-time error (if the prototype were in effect).

    The easiest way to "fix" the first case is to put:

    sub DoSomething( $\$\$ );
    (note the semicolon) near the top or your script and then drop the \'s in your calls to DoSomething.

            - tye (but my friends call me "Tye")
      Ah... so I wasn't using prototype correctly. Thanks!
Re: Modules, Prototypes, and References
by extremely (Priest) on Feb 02, 2001 at 03:18 UTC
    The real fix for this is to stop using Prototypes entirely. I've never found them to be the slightest bit helpful. They seem to exist only to confuse and to add length to the rope that young monks often use to hang themselves with. See this offsite link: FMTEYEWTKAPIP. (When you get there, you'll see why I abbreviated the title)

    --
    $you = new YOU;
    honk() if $you->love(perl)

(jeffa) Re: Modules, Prototypes, and References
by jeffa (Bishop) on Feb 01, 2001 at 23:23 UTC
    I am persusing the pages of Damian Conway's 'OOP Perl' and he says that

    "Perl does not check prototypes when a package subroutine is called as a method. . ." (page 85)

    Looks like the compiler can't check the prototypes anyways, since all Perl methods are polymorphic - you can't know until run time.

    Jeff

    L-LL-L--L-LL-L--L-LL-L--
    -R--R-RR-R--R-RR-R--R-RR
    F--F--F--F--F--F--F--F--
    (the triplet paradiddle)