Professional Web Applications Themes

subroutine definitions - PERL Beginners

I'm trying to write a subroutine that takes two scalars and two arrays as parameters. I've read that if you try to do this in a function, both arrays will get combined within '_'. Instead, I want the subroutine to take two scalars and two array references. I will not be doing any modification of the array data in the subroutine, so it will be more effecient this way, anyway. I vaguely remember reading in Learning Perl (or maybe Programming Perl) that the subroutine can be defined something like: sub my_subroutine($$\) { } My syntax may be off. Someone please ...

  1. #1

    Default subroutine definitions

    I'm trying to write a subroutine that takes two scalars and two arrays as parameters. I've
    read that if you try to do this in a function, both arrays will get combined within '_'.
    Instead, I want the subroutine to take two scalars and two array references. I will not be
    doing any modification of the array data in the subroutine, so it will be more effecient
    this way, anyway. I vaguely remember reading in Learning Perl (or maybe Programming Perl)
    that the subroutine can be defined something like:

    sub my_subroutine($$\\) {

    }

    My syntax may be off. Someone please correct me if so. (Do I really need to say this?)
    Now, how do I get those values in the subroutine?

    sub my_subroutine($$\\) {
    my ($scalar1, $scalar2, $arrayref1, $arrayref2) = _;
    }

    Another thing, how do you access an array through a reference? I know you access a hash
    through a reference by doing '$hashref->{hashkey}' instead of just '$hashref{hashkey}',
    but I've never done it with arrays (never needed to). One more thing (I promise). Do I
    need to do anything special to pass arrays as references to the function, like this:

    my_subroutine $scalar1, $scalar2, \array1, \array2;

    or can I pass them without the '\'? Sorry for all the questions in one post, but atleast
    they are all related :)

    --
    Andrew Gaffney
    Network Administrator
    Skyline Aeronautics, LLC.
    636-357-1548

    Andrew Guest

  2. #2

    Default Re: subroutine definitions

    Andrew Gaffney wrote: 

    All the values, including the two scalars, will be combined in a single
    list and be accessible through the _ array.
     

    Yes. The perlsub.pod doent which should be on your hard drive
    contains a more complete explanation of how subroutines work in Perl.
     

    Yes.
     

    To access a complete array:

    $arrayref1
     

    To access an array element:

    $arrayref1->[ 4 ]
     

    Without the '\'. perl uses the prototype ($$\\) to convert the arrays
    to references.


    John
    --
    use Perl;
    program
    fulfillment
    John Guest

  3. #3

    Default RE: subroutine definitions

    Andrew Gaffney <com> wrote:
    :
    : I'm trying to write a subroutine that takes two scalars and two
    : arrays as parameters. I've read that if you try to do this in a
    : function, both arrays will get combined within '_'.

    Andrew,

    - Stop using prototypes. You'll find it easier to write perl
    programs without them.

    - Read perlsub, perlref, and perlreftut.

    - Install perl on your local computer.

    - Experiment.

    - Try calling your subroutines with strictures and warnings
    turned on and see what happens. Your questions are /very/
    basic. I realize this is a beginners list, but you'll
    never get past beginner if you don't experiment.


    : Now, how do I get those values in the subroutine?
    :
    : sub my_subroutine($$\\) {
    : my ($scalar1, $scalar2, $arrayref1, $arrayref2) = _;
    : }

    That's about it. Though I might suggest a style change.

    - Use a variable names that describe the data, not it's
    structure.

    - Separate words in variables with underscores.

    - Use comments and white space that aids the maintainer.

    - Don't use prototypes.


    sub sales_by_quarter {
    my(
    $first_quarter_name, # scalar
    $second_quarter_name, # scalar
    $first_quarter_data, # array reference
    $second_quarter_data, # array reference
    ) = _;
    # ...
    }


    sub sales_comparison_by_quarter {

    # These are references to arrays.
    # Any changes you make *will* affect the original data.
    # Think of them as read only.
    my(
    $Q1_data, # array reference
    $Q2_data, # array reference
    ) = _;

    # Region names will default if not provided
    my $Q1_region = shift || 'Region 1';
    my $Q2_region = shift || 'Region 2';

    # ...
    }


    : Another thing, how do you access an array through a reference?
    : I know you access a hash through a reference by doing
    : '$hashref->{hashkey}' instead of just '$hashref{hashkey}', but
    : I've never done it with arrays (never needed to).

    The arrow operator (->) is used to dereference references.
    Read perlref and perl reftut.

    $second_quarter_data->[ $month ]


    : One more thing (I promise). Do I need to do anything special to
    : pass arrays as references to the function, like this:
    :
    : my_subroutine $scalar1, $scalar2, \array1, \array2;
    :
    : or can I pass them without the '\'? Sorry for all the
    : questions in one post, but at least they are all related :)

    Yes, but you have already answered this at the beginning of
    your message:

    : I'm trying to write a subroutine that takes two scalars
    : and two arrays as parameters. I've read that if you try
    : to do this in a function, both arrays will get combined
    : within '_'.

    HTH,

    Charles K. Clarkson
    --
    Mobile Homes Specialist
    254 968-8328

    Charles Guest

  4. #4

    Default Re: subroutine definitions

    Charles K. Clarkson wrote: 

    But don't prototypes make debugging a little easier by throwing warnings if you're not
    passing the correct types of arguments to the function?
     

    I will.
     

    I'm not exactly a beginner. I've been using Perl for about 8 months. It's just that I've
    never written a subroutine where I need to pass array or hash *references*.
     

    I do in real code. The above is just sample code.
     

    I don't understand how that explains how I can pass the array and hash *references* to my
    function. If I use prototypes, this is taken care of for me. If I don't use prototypes, do
    I need the '\' in front of arrays and hashes in the function call? What about anonymous
    hashes?

    my_subroutine $scalar1, $scalar2, {param1 => 'value1', param2 => 'value2'}, $arrayref;

    In the above, wouldn't the hash just get squashed into _? Wouldn't my _ end up as the
    following within the function?

    [$scalar1, $scalar2, 'param1', 'value1', 'param2', 'value2', $arrayref]

    --
    Andrew Gaffney
    Network Administrator
    Skyline Aeronautics, LLC.
    636-357-1548

    Andrew Guest

  5. #5

    Default Re: subroutine definitions

    In a message dated 2/28/2004 3:28:55 AM Eastern Standard Time,
    net writes: 

    Prototypes are useful and sometimes necessary, as in the supplied problem.
    What would be called

    my_subroutine($scalar1, $scalar2, \array1, \array2);

    , is now called

    my_subroutine $scalar1, $scalar2, array1, array2;

    This may be perfect for the problem at hand. Also, for constent values,
    prototypes ARE 100% neccisary (That's why if you do h2ph on #define PI 3.14 the
    returned subroutine has a null prototype). Also, for code reference, prototypes
    are a good, easy way to handle it (As with glob prototypes and File Handles).

    Prototypes exist for a reason. Should you use them in every case? No, but
    they have reasons to exist, and you should use them when you think it's one of
    those reasons. The real problem with prototypes is they may be overused, and
    they may be misused/misunderstood (sub my_subroutine ($scalar, array, array) {)

    -Will
    -----------------------------------
    Handy Yet Cryptic Code.
    Just to Look Cool to Look at and try to decipher without running it.

    Windows
    perl -e "printf qq.%3i\x20\x3d\x20\x27%c\x27\x09.,$_,$_ for 0x20..0x7e"

    Unix
    perl -e 'printf qq.%3i\x20\x3d\x20\x27%c\x27%7c.,$_,$_,0x20 for 0x20..0x7e'
    WilliamGunther@aol.com Guest

  6. #6

    Default Re: subroutine definitions

    Andrew Gaffney wrote: 
    >
    > But don't prototypes make debugging a little easier by throwing warnings
    > if you're not passing the correct types of arguments to the function?[/ref]

    Yes if the prototype is seen before the sub is called. However if you
    use an ampersand when you call the sub then the prototype will be
    ignored.

    # define prototype
    sub my_sub ($$\\);

    # call the sub - look - no parens!
    my_sub $scalar1, $scalar2, array1, array2;

    # call the sub - bypass prototypes! - oops
    &my_sub( $scalar3 );

    # define sub
    sub my_sub ($$\\) {
    my ( $x, $y, $ref1, $ref2 ) = _;
    ...
    }



    John
    --
    use Perl;
    program
    fulfillment
    John Guest

  7. #7

    Default Re: subroutine definitions

    Andrew Gaffney wrote:

     

    Regardless of how long you have been writing in Perl, if you have not yet:
    Started using strict and warnings in every script
    Taken time to get comfortable with references and their use as argument to function
    Then you are still a beginner.

    Prototypes are for very well-established functions that have taken on library status. There
    they can help support a more streamlined coding style. Don't use them at this point in your
    learning efforts.
     
    >
    > I do in real code. The above is just sample code.

    >
    > I don't understand how that explains how I can pass the array and hash *references* to my
    > function. If I use prototypes, this is taken care of for me.[/ref]

    Don't count on that.
     

    Bad distinction. Just put the prototypes on the shelf, please, and stick to learning Perl.
     

    If the array was declared statically, one way to offer a reference to it is indeed to offer
    the reference directly in the parameter list. You could also assign a reference to a scalar,
    and offer that scalar as an argument.

    my clunky_stay_at_home_array = qw /yada yada sis boom bah/;
    do_spectacular_things with(\clunky_stay_at_home_array);
    my $sleek_array_keycard = \clunky_stay_at_home_array;
    visit_wondrous_faraway_places( $sleek_array_keycard);
     

    Lets not jump to anonymous hashes specifically right now. how about anonymous structures in
    general? I seldom use statically declared arrays or hashes myself, unless they are scope to a
    very short, throwaway lifetime. Anonymous structures are already packed for travel:

    my $sleek_array_keycard = [qw /yada yada sis boom bah/];
    visit_wondrous_faraway_places( $sleek_array_keycard);
     

    Nope. The syntax above could also be written:

    my $blandly_named_hash_ref = {param1 => 'value1', param2 => 'value2'};
    because the braces act as operators returning a reference to the aqnonymous hash, just as
    brackets do for an anonymous array. That reference is a scalar, which cannot be flattened, as
    it is already atomic.

    my_subroutine $scalar1, $scalar2, $blandly_named_hash_ref, $arrayref;

    OTOH, if you offered a hash, rather than a reference to a hash
    my %blandly_named_hash = (param1 => 'value1', param2 => 'value2');
    my_subroutine $scalar1, $scalar2, %blandly_named_hash, $arrayref;

    or

    my_subroutine $scalar1, $scalar2, (param1 => 'value1', param2 => 'value2'), $arrayref;

    The hash contents would be flattened in the list.

    A reference is a scalar. Scalars are atomic--they do not get flattened passing through
    parameter or return list, or being stored within other structures. This is why refererences
    provide the basis for power programming.

    Joseph

    R. Guest

  8. #8

    Default Re: subroutine definitions

    R. Joseph Newton wrote: 
    >
    >
    > Regardless of how long you have been writing in Perl, if you have not yet:
    > Started using strict and warnings in every script
    > Taken time to get comfortable with references and their use as argument to function
    > Then you are still a beginner.
    >
    > Prototypes are for very well-established functions that have taken on library status. There
    > they can help support a more streamlined coding style. Don't use them at this point in your
    > learning efforts.
    >

    >>
    >>I do in real code. The above is just sample code.
    >>
    >> 
    >>
    >>I don't understand how that explains how I can pass the array and hash *references* to my
    >>function. If I use prototypes, this is taken care of for me.[/ref]
    >
    >
    > Don't count on that.
    >

    >
    >
    > Bad distinction. Just put the prototypes on the shelf, please, and stick to learning Perl.
    >

    >
    >
    > If the array was declared statically, one way to offer a reference to it is indeed to offer
    > the reference directly in the parameter list. You could also assign a reference to a scalar,
    > and offer that scalar as an argument.
    >
    > my clunky_stay_at_home_array = qw /yada yada sis boom bah/;
    > do_spectacular_things with(\clunky_stay_at_home_array);
    > my $sleek_array_keycard = \clunky_stay_at_home_array;
    > visit_wondrous_faraway_places( $sleek_array_keycard);
    >

    >
    >
    > Lets not jump to anonymous hashes specifically right now. how about anonymous structures in
    > general? I seldom use statically declared arrays or hashes myself, unless they are scope to a
    > very short, throwaway lifetime. Anonymous structures are already packed for travel:
    >
    > my $sleek_array_keycard = [qw /yada yada sis boom bah/];
    > visit_wondrous_faraway_places( $sleek_array_keycard);
    >

    >
    >
    > Nope. The syntax above could also be written:
    >
    > my $blandly_named_hash_ref = {param1 => 'value1', param2 => 'value2'};
    > because the braces act as operators returning a reference to the aqnonymous hash, just as
    > brackets do for an anonymous array. That reference is a scalar, which cannot be flattened, as
    > it is already atomic.
    >
    > my_subroutine $scalar1, $scalar2, $blandly_named_hash_ref, $arrayref;
    >
    > OTOH, if you offered a hash, rather than a reference to a hash
    > my %blandly_named_hash = (param1 => 'value1', param2 => 'value2');
    > my_subroutine $scalar1, $scalar2, %blandly_named_hash, $arrayref;
    >
    > or
    >
    > my_subroutine $scalar1, $scalar2, (param1 => 'value1', param2 => 'value2'), $arrayref;
    >
    > The hash contents would be flattened in the list.
    >
    > A reference is a scalar. Scalars are atomic--they do not get flattened passing through
    > parameter or return list, or being stored within other structures. This is why refererences
    > provide the basis for power programming.[/ref]

    I'm getting conflicting advice between your post and another post to this thread. Maybe if
    I post my code, you can recommend the best way for me to setup my functions and the calls
    to them (and whether to prototype them). This code will be for an Apache 1.3.x/mod_perl
    1.x/Mason website.

    I am writing a module that contains functions that I commonly use in my scripts. I have
    written a lot of scripts that generate HTML reports from the data in the MySQL DB. My boss
    wants these reports to spit out their data either in HTML or Excel. I had the idea of
    writing functions that take a series of scalars and arrays that describe the data to be in
    the report.

    The functions (generate_report_html() and generate_report_excel()) actually process the
    arrays and such and generate the reports in HTML or Excel. This makes it easier to create
    new reports and greatly cuts down on code duplication. Here are my functions (keep in mind
    I only started writing them at 1AM and they aren't near finished):

    <code>
    package Skyline;

    <big SNIP of other module code>

    sub generate_report_html($\\) {
    my ($title, $columns, $data) = _;
    print <<' EOF';
    <html>
    <body>
    <center><img src='/original_logo_60pc.jpg'><p>
    <h2>$title Report</h2></center>
    <p>
    <table width=100%>
    <tr>
    EOF
    foreach ($columns) {
    print "<td><b><u>$_</u></b></td>";
    }
    print "</tr>\n";
    foreach my $row ($data) {
    print "<tr>";
    foreach ($row) {
    print "<td>$_</td>";
    }
    print "</tr>\n";
    }
    print <<' EOF';
    </table>
    </body>
    </html>
    EOF
    }

    sub generate_report_excel($\\) {
    my ($title, $columns, $data) = _;
    # No other code written for this function yet
    }
    </code>

    A typical script that generates a report using these functions would look like:

    <code>
    use Skyline;
    use CGI;

    my $cgi = new CGI;
    my data;
    my $dbh = init_db(); # Module function to connect to MySQL DB using DBI
    my $sth = $dbh->prepare("SELECT fname, lname, homephone FROM people ORDER BY lname");
    $sth->execute;
    my $ref;
    while($ref = $sth->fetchrow_hashref) {
    push data, ["$ref->{lname}, $ref->{fname}", "$ref->{homephone}"];
    }

    my columns = ("Name", "Phone Number");
    generate_report_html("Customers", columns, data);
    </code>

    This then generates a nice formatted HTML report with minimal code. What would you change
    (if anything) about the above code (module or report scripts)?

    --
    Andrew Gaffney
    Network Administrator
    Skyline Aeronautics, LLC.
    636-357-1548

    Andrew Guest

  9. #9

    Default Re: subroutine definitions

    On Feb 28, 2004, at 7:05 PM, Andrew Gaffney wrote:
     

    Yes, you've hit on a holy war among us Perl programmers. A lot of us
    feel strongly about prototypes, one way or another.

    Perl's prototypes are a little flimsy at times. It's already been
    shown that just adding an ampersand to the call bypasses them, which
    would completely change your subroutine if references are involved,
    wouldn't it? Perl's method invocation system also bypasses them. For
    reasons like this (plus others), some of us try to avoid them. Of
    course, you shouldn't be putting that ampersand on the calls and we're
    not talking about methods here, so they should be safe.

    Prototype's solve your problem and they're in Perl, so you can use
    them. We won't come to your workplace and take your computer away if
    you do, no matter how much Joseph wants to :D. If you do us them, just
    be aware that you can't always use them. There are situations where
    they will fail you. No big deal, it doesn't look like this is one of
    them.

    If you don't/can't use them, you can of course always just pass the
    references manually. Something like:

    subroutine_call($something, $something_else, \array, \another_array);

    That works fine and arguably shows what's going on a little better. Of
    course, you'll need to doent this for the users of your code. Then
    again, you'll probably need to doent that they don't have to do
    this, if you go the prototype's route. No escaping doentation,
    shucks.

    The Moral: Both will work for you. Prototypes should be fine here.
    You can get by without them. Relax and use whatever feels right to you
    and your users. There is no right or wrong answer, if it runs. ;)

    James

    James Guest

  10. #10

    Default Re: subroutine definitions

    Andrew Gaffney wrote:
     
     

    Are you sure? In what way? Your response left the entire body of my post intact, so that doesn't
    narrow down the points of perceived conflict. My perception is that we have all been reinforcing
    each other's point that prototypes are probably not a good investment of your coding energy right
    now. Can you be more specific?
     

    $data is prototyped as an array/list, but you receive it here as a scalar. If you must use the
    damned prototype, it should be:
    sub generate_report_html($\\\)

    or your p[arameter get should be:
    my ($title, $columns, data) = _;

     

    Same issue as with the above. It may work, but only by accident.
     

    I'd get rid of the prototypes. I would then offer only references as function arguments, unless
    there is a specific reason why you want the function to deal with only the list of values contained
    by the array, rather than the array itself.

    Joseph

    R. Guest

  11. #11

    Default Re: subroutine definitions

    James Edward Gray II wrote: 
    >
    > Yes, you've hit on a holy war among us Perl programmers. A lot of us
    > feel strongly about prototypes, one way or another.
    >
    > Perl's prototypes are a little flimsy at times. It's already been shown
    > that just adding an ampersand to the call bypasses them, which would
    > completely change your subroutine if references are involved, wouldn't
    > it? Perl's method invocation system also bypasses them. For reasons
    > like this (plus others), some of us try to avoid them. Of course, you
    > shouldn't be putting that ampersand on the calls and we're not talking
    > about methods here, so they should be safe.
    >
    > Prototype's solve your problem and they're in Perl, so you can use
    > them. We won't come to your workplace and take your computer away if
    > you do, no matter how much Joseph wants to :D. If you do us them, just
    > be aware that you can't always use them. There are situations where
    > they will fail you. No big deal, it doesn't look like this is one of them.
    >
    > If you don't/can't use them, you can of course always just pass the
    > references manually. Something like:
    >
    > subroutine_call($something, $something_else, \array, \another_array);
    >
    > That works fine and arguably shows what's going on a little better. Of
    > course, you'll need to doent this for the users of your code. Then
    > again, you'll probably need to doent that they don't have to do this,
    > if you go the prototype's route. No escaping doentation, shucks.[/ref]

    Really, I'm the only user of my code. I don't expect to get replaced anytime soon as my
    boss also doubles as my father ;) Besides, I certaintly don't want to make things easier
    for my replacement (if there ever is one).
     

    This has all been very helpful and informative. Thanks.

    --
    Andrew Gaffney
    Network Administrator
    Skyline Aeronautics, LLC.
    636-357-1548

    Andrew Guest

  12. #12

    Default Re: subroutine definitions

    R. Joseph Newton wrote: 

    >
    > Are you sure? In what way? Your response left the entire body of my post intact, so that doesn't
    > narrow down the points of perceived conflict. My perception is that we have all been reinforcing
    > each other's point that prototypes are probably not a good investment of your coding energy right
    > now. Can you be more specific?[/ref]

    I was refering to the prototyping. You say no while another poster said yes a few minutes
    before/after.
     
    >
    >
    > $data is prototyped as an array/list, but you receive it here as a scalar. If you must use the
    > damned prototype, it should be:
    > sub generate_report_html($\\\)
    >
    > or your p[arameter get should be:
    > my ($title, $columns, data) = _;[/ref]

    It seems to work fine the way I have it, but I'll change it one way or the other if it
    makes a difference.
     
    >
    >
    > Same issue as with the above. It may work, but only by accident.
    >

    >
    > I'd get rid of the prototypes. I would then offer only references as function arguments, unless
    > there is a specific reason why you want the function to deal with only the list of values contained
    > by the array, rather than the array itself.[/ref]

    I didn't mean it to work that way. Remember, I am only a *beginner* ;) Thanks for all the
    help.

    --
    Andrew Gaffney
    Network Administrator
    Skyline Aeronautics, LLC.
    636-357-1548

    Andrew Guest

  13. #13

    Default Re: subroutine definitions

    "R. Joseph Newton" wrote: 
    >
    > $data is prototyped as an array/list, but you receive it here as a scalar. If
    > you must use the damned prototype, it should be:
    > sub generate_report_html($\\\)[/ref]
    ^^
    ^^
     

    Please read the 'Prototypes' section of perlsub.pod. Andrew had $data
    prototyped as a reference to an array which is a scalar value. The
    prototype '\\' is an error and won't run. If you want to use data
    instead of $data then the prototype should be ($\) but that will copy
    the entire array and not just a single scalar.


    John
    --
    use Perl;
    program
    fulfillment
    John Guest

  14. #14

    Default RE: subroutine definitions

    Andrew Gaffney <com> wrote:
    : <code>
    : package Skyline;
    :
    : <big SNIP of other module code>
    :
    : sub generate_report_html($\\) {
    : my ($title, $columns, $data) = _;

    Here begins my problems with prototypes. Let's try
    this sample script:

    sub generate_report_html($\\);

    my $title = 'foo';
    my column_names = 1 .. 4;
    my data = ( [1 .. 4], [5 .. 8] );

    generate_report_html $title, column_names, data;

    sub generate_report_html($\\) {
    my ($title, $columns, $data) = _;
    print "Report Done";
    }


    Everything is just fine until I decide to get my
    column names from a subroutine:

    generate_report_html $title, column_names(), data;

    sub column_names {
    return 1 .. 4;
    }

    Now I have to go into a library and find out why
    things are failing and repair them. If I repair them,
    do I now have a problem with all the other programs
    written using that library of sub routines?



    I could massage the output of column_names() to
    work with generate_report_html(),

    generate_report_html $title, { [ column_names() ] }, data;


    Or I could change the output of column_names(). But
    if column_names() is another library sub routine I'm back
    to square one.

    I like perl because I tend to not have to jump through
    hoops to program. Protoypes limit me too much. I'd rather
    not have to plan so far ahead when solving a problem.


    HTH,

    Charles K. Clarkson
    --
    Mobile Homes Specialist
    254 968-8328



































    Charles Guest

  15. #15

    Default Re: subroutine definitions

    Charles K. Clarkson wrote: 

    Based on your advice and that of other posters, I have removed the prototype. I was
    already sending the function array/hash references, so I didn't have to change anything.

    --
    Andrew Gaffney
    Network Administrator
    Skyline Aeronautics, LLC.
    636-357-1548

    Andrew Guest

  16. #16

    Default Re: subroutine definitions

    "Charles K. Clarkson" wrote:
     
     

    which could also be written:
    sub generate_report_html($$$);

    with much greater clarity.
     

    would work well as:
    generate_report_html $title, \column_names, \data;
     

    Perhaps because the sub neither does nor supervises the doing of any real work?
    I don't think it would work if the sub tried to accomplish anything, given the
    arguments offered.
     

    Do0n't use functions returning raw lists as function arguments. Function
    arguments should be precise and predictable. If anything, the function called
    by this should be prototyped:

    sub generate_report_html ($$$$$);
     

    Okay, Charles, now you are alluding to something we have no context to
    understand. Are you saying that this would be the problem if the above function
    were in a library, or ...

     

    HI Charles,

    I agree strongly with your thesis, but in fairness, I would have to say that the
    problems here arise more from type-confusion than from defects of prototypes
    themselves. People seem to take that final in the prototype the wrong way.
    My impression is that it essentially throws the prototype back open. All
    arguments up to that bag sign are strictly prototyped. If the indicator is
    \, then the referennt of that scalar must be an array, likewise with \%. After
    that point, if the list is terminated with a bag sign, then all further argument
    become part of the bag, making the rest of the argument list equivalent to that
    in an unprototyped function.

    You could say that Perl subroutines, unless otherwise indicated have the
    implicit prototype
    sub_name();
    indicating a single flat list, of indeterminate length, of scalars, some of
    which may well be references to aggregates.

    The bag indicator anywhere else in the prototype would create insoluble errors,
    because the bag would take in all remaining arguments, leaving none to fulfill
    any type specifications to follow.

    Joseph

    R. Guest

  17. #17

    Default Re: subroutine definitions

    R. Joseph Newton wrote: 

    >
    > which could also be written:
    > sub generate_report_html($$$);
    >
    > with much greater clarity.[/ref]

    This is not the same. A '$' in the subroutine prototype means a scalar,
    any scalar, while '\' means that the argument must start with '' and
    it will be passed to the subroutine as an array reference.

    See perldoc perlsub.
    --
    ZSDC


    Zsdc Guest

  18. #18

    Default Re: subroutine definitions

    zsdc wrote:
     
    > > 
    > >
    > > which could also be written:
    > > sub generate_report_html($$$);
    > >
    > > with much greater clarity.[/ref]
    >
    > This is not the same. A '$' in the subroutine prototype means a scalar,
    > any scalar, while '\' means that the argument must start with '' and
    > it will be passed to the subroutine as an array reference.
    >
    > See perldoc perlsub.
    > --
    > ZSDC[/ref]

    Got it. I'll still stick with what I said, though. This "feature" offered by
    Perl prototypes strikes me as primarily a seed of confusion. Particularly in
    the context of a beginners list, it obscures the underlying issue concerning
    subroutine arguments--that subroutines take only a list of scalars as their
    arguments. When we have so many beginners tripping themselves up by trying to
    avoid the use of explicit references, this syntactic "convenience" only prolongs
    the pain and confusion.

    I must say, this is clearing up a point of cusiosity for me, as to how functions
    like
    chomp lines;
    can work on the original structure as called. Although it's made me raise my
    eyebrows off and on, I've never pursued it. The Perl core can take take of
    itself. The functions are well-doented, so you can follow the calling
    sequence shown in the docs, and they work. Nevertheless, there is a real
    ambiguity about the arguments offered to a function making use of this feature.

    I would see this in a more positive light, perhaps, if prototypes were more
    required for all functions, particularly if they offered named formal
    parameters. In those cirstances, prototypes would offer great benefits of
    clarity, since one could always refer to the signature of any function to see
    whether the argument should be taken by value or reference. The random
    application of prototypes to allow inconsistent calling syntax does not seem to
    me to add any clarity.

    Joseph


    R. Guest

  19. #19

    Default Re: subroutine definitions

    R. Joseph Newton wrote:
     


    No, but there-in lies the true power and true nightmare that is Perl.

    However, it is better to go with your training and experience and simply
    write Perl code according to your own/company guidelines so that if you
    need to look back (or if someone else needs to look back for you) you
    will know why things were written that way in the first place.

    Even Larry Wall has stated "Do I really need ten ways to do something?"

    Functionality and Clarity are more important over Compactness and Speed.
    I mean what good is a piece of code to find words with "even sets"[1]
    of vowels if no one else understands or can maintain it.

    Perl already has a bad history of being WRITE-ONLY; lets see if we can
    all make it re-usable?

    -Bill-
    __Sx__________________________________________
    http://youve-reached-the.endoftheinternet.org/

    [1] 'even' would match as it has 2 e's...
    Wc Guest

  20. #20

    Default Re: subroutine definitions

    R. Joseph Newton wrote: 

    Confusion? You should read 6th Apocalypse by Larry Wall and the
    appropriate Exegesis by Damian Conway:

    http://dev.perl.org/perl6/apocalypse/A06.html
    http://dev.perl.org/perl6/exegesis/E06.html

    Now, _that_ is confusing. :)

    But seriously, I see you point. Perl 5 prototypes were invented mostly
    to make things like $x = pop array work but there is nothing you can do
    with prototypes which you cannot do without them, only with different
    function call syntax.
     

    True. This is probably one of those parts of Perl which should not be
    the first thing told beginners.
     

    Yes. This, and e.g. things like this:

    print int $x, int $y;

    with int, unlike print, acting as a unary operator and getting only one
    argument, thanks to its ($) prototype.
     

    They will in Perl 6.

    http://dev.perl.org/perl6/
    --
    ZSDC

    Zsdc Guest

Page 1 of 2 12 LastLast

Similar Threads

  1. AICS and PSCS PMS definitions
    By Brad_Pettengill@adobeforums.com in forum Adobe Illustrator Macintosh
    Replies: 1
    Last Post: April 9th, 04:50 AM
  2. Question about SQL table definitions
    By Kevin Thorpe in forum PHP Development
    Replies: 3
    Last Post: November 27th, 09:04 AM
  3. Group definitions
    By Vincent in forum AIX
    Replies: 3
    Last Post: September 19th, 02:27 PM
  4. Site Definitions
    By mbstone webforumsuser@macromedia.com in forum Macromedia Dreamweaver
    Replies: 2
    Last Post: July 24th, 06:40 PM
  5. how to backup site definitions?
    By felixc webforumsuser@macromedia.com in forum Macromedia Dreamweaver
    Replies: 0
    Last Post: July 10th, 09:19 AM

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139