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

Assuming that libraries are being created, how does one take advantage of prototypes in the case where subroutines are spread across files? Given the following code:
#!/usr/bin/perl use strict; require 'include.pl'; sub localAdd($$); #sub remoteAdd($$); # Is this required? my $i; $i = localAdd 1, 2; #$i = localAdd 1, 2, 3; # error: "Too many arguments for main:local +Add at test.pl line 9, near "3;" print "i = $i\n"; #$i = remoteAdd 1, 2; # error: "Number found where operator expec +ted at test.pl line 15, near "remoteAdd 1" (Do you need to predeclare + remoteAdd?) #$i = remoteAdd 1, 2, 3; #print "i = $i\n"; $i = remoteAdd(1, 2); $i = remoteAdd(1, 2, 3); # prototype in include.pl is not honored print "i = $i\n"; sub localAdd($$) { my ($i, $j) = @_; return $i + $j; }
where include.pl contains the following:
sub remoteAdd($$); # This appears to have no effect across files... sub remoteAdd($$) { # die "incorrect #arguments in remoteAdd" unless @_ == 2; my ($i, $j) = @_; return $i + $j; } 1;
Prototypes get around expliciting checking for the number of parameters passed to a subroutine, but when subroutines are spread across multiple files, I no longer am seeing the interpreter perform this check for me. How do I get this functionality back for free?

Thanks for any insight on this issue.

Replies are listed 'Best First'.
Re: subroutine prototypes effectiveness across files?
by chromatic (Archbishop) on Oct 24, 2003 at 22:25 UTC

    With the caveat that I only use prototypes when I want something to act like a built-in operator, require is tripping you up. Since it happens at run-time, it's too late for perl to check the prototypes on existing code. The simplest solution is to wrap your require lines in BEGIN blocks.

    Of course, someone will come flying around the corner to tell you not to use prototypes and someone else will say "you should write a module instead", which are both reasonable ideas, if a lot more work.

      So out of curiosity, what is the mechanism for adding new routines which are to act like built-in functions if parameter checking is desired?

      As it is, prototyping has limited appeal if it is restricted to same file usage.

      Thanks for setting me straight. I'll have to look more in earnest at objects.

        what is the mechanism for adding new routines which are to act like built-in functions if parameter checking is desired?

        Prototyping, as I said.

        As it is, prototyping has limited appeal if it is restricted to same file usage.

        There is no such restriction.

        While I said that require fires too late for perl to do anything with your prototypes, I also gave you a suggestion on how to require your other files in time for perl to check the prototypes on your functions. Give it a whirl; I think you'll find that it works as you expected your first attempt to work.

Re: subroutine prototypes effectiveness across files?
by sauoq (Abbot) on Oct 25, 2003 at 00:16 UTC

    Just as chromatic prognosticated...

    Don't use prototypes. At least, don't use them without being aware of their limitations and the fact that they are poorly named. Prototypes aren't prototypes like you find in other languages. They are good for three things:

    1. Hinting that a sub might be inlinable (with an empty prototype.)
    2. Emulating builtin behavior.
    3. Extending the language syntax.

    While prototypes may be good for tasks two and three above, doing either of them usually isn't a good idea in the first place.¹ Hence, prototypes have very limited use.

    I urge everyone to read and understand Tom Christiansen's article on prototypes before using them.

    1. There are exceptions of course, but that's what they are. . . exceptions.

    -sauoq
    "My two cents aren't worth a dime.";