Beefy Boxes and Bandwidth Generously Provided by pair Networks
Come for the quick hacks, stay for the epiphanies.
 
PerlMonks  

Function Prototypes

by KimberTLE (Initiate)
on Nov 24, 2015 at 01:18 UTC ( [id://1148461]=perlquestion: print w/replies, xml ) Need Help??

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

Having difficulty coming-up with what the prototype for my sub might look like. If coded as is (below), the sub works; the caller sends named parameters, the sub checks for useful data, does the caller's bidding. A sample of things I've tried for prototypes are:
sub ConfigRead($ @ %); sub ConfigRead(;$ @ %); sub ConfigRead($ \@ \%); sub ConfigRead(;$ \@ \%);
My actual code without the prototype resembles this:
#!/usr/bin/perl -w use strict; my @aFieldHeaders; my %hFieldConfigs; my $sConfigFile = 'mydata.csv'; ConfigRead(sFILE => $sConfigFile, apHEAD => \@aFieldHeaders, hpFIELDCONF => \%hFieldConfigs); # my array and hash now have some cool stuff in 'em! sub ConfigRead { my %hArgs = ( sFILE => 'BAD', # lazy user alert! whine & die apHEAD => 'BAD', # ^^^ see comment above hpFIELDCONF => 'BAD', # by now you know the drill! @_, # user demands come from here ); # stick some cool stuff in their variables }
Suggestions, solutions and/or winning lottery ticket numbers for Wednesday's drawing gratefully accepted!

Replies are listed 'Best First'.
Re: Function Prototypes
by GrandFather (Saint) on Nov 24, 2015 at 02:02 UTC

    Use undef to mean 'BAD' and your sample sub becomes:

    sub ConfigRead { my %hArgs = @_; # stick some cool stuff in their variables }

    Then instead of:

    die "horribly" if $hArgs{sFILE} eq 'BAD';

    you can:

    die "horribly" if !exists $hArgs{sFILE};

    or:

    $hArgs{sFILE} //= 'default.sFile';

    as appropriate.

    Premature optimization is the root of all job security
    A reply falls below the community's threshold of quality. You may see it by logging in.
Re: Function Prototypes
by hippo (Bishop) on Nov 24, 2015 at 13:21 UTC

    Your args as in the example are a hash, so in the absence of any indication of why you want to use prototypes the obvious works for me:

    #!/usr/bin/perl -w use strict; my @aFieldHeaders; my %hFieldConfigs; sub ConfigRead (%); my $sConfigFile = 'mydata.csv'; ConfigRead(sFILE => $sConfigFile, apHEAD => \@aFieldHeaders, hpFIELDCONF => \%hFieldConfigs); # my array and hash now have some cool stuff in 'em! sub ConfigRead (%) { my %hArgs = ( sFILE => 'BAD', # lazy user alert! whine & die apHEAD => 'BAD', # ^^^ see comment above hpFIELDCONF => 'BAD', # by now you know the drill! @_, # user demands come from here ); # stick some cool stuff in their variables }

    But as everyone else has said: don't do that unless you have a good reason.

      You, hippo, are my hero! And now that I see it, it makes perfect sense. Occam's Razor, after a good stropping. As promised: THANK YOU!

        I still do not understand your original reasons for wanting to use prototypes, nor do I know if hippo's reply has dissuaded you, but if you are not dissuaded, here's an example of why prototypes are not useful as you seem to wish to use them:

        c:\@Work\Perl\monks>perl -wMstrict -le "use Data::Dump qw(dd); ;; sub S_ { my %h = @_; dd \%h; } sub Sh (%) { my %h = @_; dd \%h; } sub Sa (@) { my %h = @_; dd \%h; } ;; S_(qw(a b c)); Sh(qw(a b c)); Sa(qw(a b c)); " Odd number of elements in hash assignment at -e line 1. { a => "b", c => undef } Odd number of elements in hash assignment at -e line 1. { a => "b", c => undef } Odd number of elements in hash assignment at -e line 1. { a => "b", c => undef }
        The warning is in the  'misc' class, and escalating such warnings to FATALity would at least prevent the code from soldiering on regardless, but of course that has nothing to do with the prototype.


        Give a man a fish:  <%-{-{-{-<

Re: Function Prototypes
by muba (Priest) on Nov 24, 2015 at 01:37 UTC
    If coded as is (below), the sub works;

    Cool cool.

    There's a lot of things to say about the way Perl passes arguments into a subroutine through this weird @_ variable. But don't you just love it how it allows you to write stuff like my %hArgs = (default1 => "foo", default2=> "bar", @_); ... inside a sub, and then call that sub with ConfigRead default2 => "banana juice", extra => "new key/value pair w00t w00t"; and it just works and you preserve one default setting, override another, and even introduce a third setting? It's things like that make adore this language.

    So thumbs up to you, KimberTLE, for coming up with a solution that works. And I don't mean that sarcastically, I am indeed sincere. So... is there a question?

Re: Function Prototypes
by Anonymous Monk on Nov 24, 2015 at 01:48 UTC
Re: Function Prototypes
by Anonymous Monk on Nov 24, 2015 at 01:32 UTC
    IMHO, it should look like this:
    # the line above was intentionally left blank
    In other words, don't use prototypes at all...
      Thank you for your "In other words, don't use prototypes at all..." quip. It was certainly useful, and I shall cherish it for all time! Now, why do you think I asked for assistance with how to code the prototypes? Do you think it's because I don't like prototyping, or do you think it's because I prefer prototyping? I'll give you a few seconds to consider your answer...

        If you come from a strictly typed language like C++, prototypes seem like a good idea. In Perl almost always they aren't. Which is why mentioning prototypes in Perl often elicits a "Don't do that!" response.

        What is your good reason for using prototypes? (There are some.)

        Your sample non-prototype code looks pretty good to me because you have effectively named the parameters where they are being passed. That is hugely better documentation for someone reading the code later than simply passing a list and hoping for the best. Perl prototypes don't give type safety - they tend to enforce type matching which puts them on a level with C style casts. See Prototypes for the full glory of function prototyping.

        Premature optimization is the root of all job security
Re: Function Prototypes
by u65 (Chaplain) on Nov 24, 2015 at 12:32 UTC

    If you absoulutely must use function protypes I suggest you convert to Perl 6.

        Aha! Thanks, davies, that's the one I remember seeing but couldn't find this morning. Excellent suggestion!

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others pondering the Monastery: (7)
As of 2024-03-28 18:42 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found