Beefy Boxes and Bandwidth Generously Provided by pair Networks
Pathologically Eclectic Rubbish Lister
 
PerlMonks  

Good use for prototypes. On methods no less!

by polymorpheus (Novice)
on Jun 01, 2012 at 19:23 UTC ( [id://973850]=perlquestion: print w/replies, xml ) Need Help??

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

I came up with what I think is another valid reason for using function prototypes even though I generally agree they should not be used.

And, of all places, I am suggesting using them on methods. Yes methods, where prototypes are known not to work.

So why you ask?

To prevent people from calling your methods as functions.

For example, the docs for UNIVERSAL::isa say not to call it as a function. But people do it all the time. if they had declared it like this:

sub isa() { ... }
then they could have prevented this widespread misuse of the API.

Has anyone seen this mentioned anywhere else? I don't think PBP or Modern Perl mention this.

Thanks!

Replies are listed 'Best First'.
Re: Good use for prototypes. On methods no less!
by chromatic (Archbishop) on Jun 01, 2012 at 20:00 UTC
    &UNIVERSAL::isa( $invocant, 'ClassName' ); # still broken
Re: Good use for prototypes. On methods no less!
by Eliya (Vicar) on Jun 01, 2012 at 19:45 UTC

    if they had declared it like this:

    sub isa() { ... }

    then they could have prevented this widespread misuse of the API.

    How so (even if protoypes did work with methods)?

    Wouldn't the effect rather be that you could now no longer call it as a method, nor with any parameter?

      Prototypes do nothing on method calls. There is plenty of talk about this in various forums. So they do not affect good users.

      If someone tries to call UNIVERSAL::isa(...) with arguments (what use would it be otherwise) they will get the compile time error.

      For example, this:

      > perl -e 'sub method() { }; main->method(1, 2, 3);'
      works, but this:
      > perl -e 'sub method() { }; main::method("main", 1, 2, 3);' Too many arguments for main::method at -e line 1, near "3)" Execution of -e aborted due to compilation errors.
      does not.

        Prototypes do nothing on method calls.

        Ah, sorry, I misread...   I thought you were suggesting that they should work with methods, too, and that this way all kind of problems (including the example presented) could be solved.  My bad!

Re: Good use for prototypes. On methods no less!
by thargas (Deacon) on Jun 04, 2012 at 11:26 UTC

    Hmmm. I can certainly understand why PBP wouldn't refer to this as I can't imagine anyone would claim that this is a best practice.

    Why are you wanting to do this? Are you really having that many people who can't read the docs? Personally, if someone has ignored the docs sufficiently to be calling a method as a function, I don't really care what happens to their code; it's unlikely to do anything useful and they'll notice that, unless they don't care, in which case ...

      I don't necessarily want or need to do this, but yes, I was considering this in the context of best practices.

      As you note, and Chromatic points out, the malicious user can easily get around this defense, but what about the novice user? it might help prevent a few bad cases from creeping into the code base. I have also been considering recommending an empty prototype on functions that do not take any args as this appears to be the one case where they are useful at pointing out usage errors early (compile time) to the user.

      At a minimum, I am wondering about a perl critic exception to allow smart use of prototypes.

        OK. If you're considering this in the context of novice users, I would say, please don't do this. The error you get is going to be misleading:

        Too many arguments for Thing::hack at ./proto-method line 16, near "1) +" Execution of ./proto-method aborted due to compilation errors.

        If your goal is to help novice users, this seems to me not to be the a good idea, as the error says nothing about the actual problem. I don't think that this idea will help anyone, except in the sense that calling the method as a function will fail, unless they pass it no args.

        Sorry. I've got no alternative suggestion, but I don't like this idea.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://973850]
Approved by davido
Front-paged by Old_Gray_Bear
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others sharing their wisdom with the Monastery: (3)
As of 2024-04-23 22:17 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found