Beefy Boxes and Bandwidth Generously Provided by pair Networks
Welcome to the Monastery
 
PerlMonks  

Re: What's the better Perl style? Define parameters or not?

by biohisham (Priest)
on Jan 05, 2010 at 04:36 UTC ( [id://815691]=note: print w/replies, xml ) Need Help??


in reply to What's the better Perl style? Define parameters or not?

That depends on the requirements and flexibility you want to impose when working with subroutines, The different ways you can declare subroutines in Perl are a combination of what you have read in these books, and generally, to brief it:
  • sub SUBNAME
  • sub SUBNAME(PROTOTYPE)
  • sub SUBNAME {BLOCK}
  • sub SUBNAME(PROTOTYPE){BLOCK}

As the term "prototype" suggests, you can tell Perl of the type and number of arguments you wanna pass to this subroutine and whether any of these types can be optional, therefore, it is a mechanism to make sure that you don't pass an array to a subroutine when it expects a scalar...

sub SUBNAME($@;\%)
This subroutine above is called with a scalar, list and followed by an optional hash...

You can call a subroutine in a number of ways too, but for simplicity I'd only mention two ways:
&SUBNAME # & dereferencer is implicit and can be dropped at times. #OR... SUBNAME()
How does this come in context with declaring prototypes?... using the & form of calling a subroutine would deactivate prototype checking that means, as long as you don't preface the subroutine names with & the prototypes provided in the declaration would affect/interfere with the calls to the subroutine...

NOTE: I learnt this from The Perl Black Book...

Update: ikegami and BrowserUk, I am happy to have erred and I am happy to have been guided, I was under the impression that prototypes could help validating a subroutine passed arguments, and just verifying this I did not get a proof of concept that such a behavior exists but this left me confused on what I read reviewing the lessons and with a question of "why use them prototypes after all if they are not good at checking functions or are ignored upon such validation?" , I really hope I am not being a dumb now...


Excellence is an Endeavor of Persistence. Chance Favors a Prepared Mind.

Replies are listed 'Best First'.
Re^2: What's the better Perl style? Define parameters or not?
by BrowserUk (Patriarch) on Jan 05, 2010 at 05:00 UTC
    I learnt this from The Perl Black Book...

    You need to review the lessons.

    Your prototype means that any optional hashref supplied will be assigned to the array, and will never get assigned to the appropriate place inside the sub:

    sub test($@;\%){ my( $scalar, @array, $hashref ) = @_; pp $_ for $scalar, \@array, $hashref; };; $s='fred'; @a = 1..10; %h = 1..10;; test( $s, @a, \%h );; "fred" [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, { 1 => 2, 3 => 4, 5 => 6, 7 => 8, 9 => 10 }, ] undef

    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.
Re^2: What's the better Perl style? Define parameters or not?
by ikegami (Patriarch) on Jan 05, 2010 at 05:54 UTC

    You are also wrong about \%. \% means the sub requires a hash, not a hashref.

    >perl -le"sub f(\%) { print $_[0] } f(\%h)" Type of arg 1 to main::f must be hash (not reference constructor) at - +e line 1, at end of line Execution of -e aborted due to compilation errors. >perl -le"sub f(\%) { print $_[0] } f(%h)" HASH(0x238be4)

    A hashref is what the sub receives.

    There is no prototype that will enforce what you desire (a scalar, an array and an optional hashref). Prototypes aren't good at validation.

Re^2: What's the better Perl style? Define parameters or not?
by cdarke (Prior) on Jan 05, 2010 at 11:53 UTC
    sub SUBNAME($@;\%) This subroutine above is called with a scalar, array and followed by an optional hash...

    Others, more worthy than I, have dealt with the hashref parameter. The @ does not mean an array, it means a list. Consider:
    sub mysub($@\%) { my ($one, @two, $ref) = @_; print "@two\n"; } mysub('a','b','c','d');
    Gives:
    b c d
    The minimum length of a list is zero elements, so the following "works" (in that no error is reported) as well:
    mysub('a');
    If you want to force an array, use \@. Prototypes are useful for forcing the correct type of reference being passed at compile-time (as opposed to runtime checks) but are so easy to circumvent, even accidently, that they can lull you into a false sense of security.

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others admiring the Monastery: (4)
As of 2024-04-25 13:19 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found