question regarding multiple args to sub

Discussion in 'Perl Misc' started by ktom, Aug 15, 2003.

  1. ktom

    ktom Guest

    I have to subs in which i am attempting to pass multiple args to and i
    have managed to get it to work, after spending all afternoon trying to
    get my brain around it. I still don't have my brain around and the
    solution seems absurd!!

    below are snippets...

    1st call:

    &printVec( \@spline, \@indx, \@port1 );
    }

    1st working sub:

    sub printVec {
    #our @spline;
    # my (@spline,@indx,@port) = @_ ;
    # print "pre @$spl, @$indx, @$port\n";
    # print "spline @spline\n";
    my ($spl,$indx,$port) = @_ ;
    my @prt = @$port ;
    my @ndx = @$indx ;
    my @spline = @$spl ;


    2nd call:

    &printTset( \@indx, $vect, $cmmnt ) ;
    }

    2nd working sub:

    sub printTset {
    my ( $indx, $vct, $cmt) = @_ ;
    my @ndx = @$indx;
    my $vect = $vct;
    my $cmmnt = $cmt;

    if i don't use the \ on the passed parameters, it seems to merge them
    all into one big array.. blahh.

    this seems like a lot of code, seemingly redundant to my wee perl mind,
    to pass values to a subroutine.

    what magic am i missing or is this just the way it is???

    thanks..
     
    ktom, Aug 15, 2003
    #1
    1. Advertising

  2. ktom

    Bob Walton Guest

    ktom wrote:

    > I have to subs in which i am attempting to pass multiple args to and i
    > have managed to get it to work, after spending all afternoon trying to
    > get my brain around it. I still don't have my brain around and the
    > solution seems absurd!!
    >
    > below are snippets...
    >
    > 1st call:
    >
    > &printVec( \@spline, \@indx, \@port1 );


    ----------^

    Any more (that is, with Perl's less than many years old), you shouldn't
    use the & in your call unless you actually want the specific
    functionality it provides. See:

    perldoc perlsub

    for details.


    > }
    >
    > 1st working sub:
    >
    > sub printVec {
    > #our @spline;
    > # my (@spline,@indx,@port) = @_ ;
    > # print "pre @$spl, @$indx, @$port\n";
    > # print "spline @spline\n";
    > my ($spl,$indx,$port) = @_ ;
    > my @prt = @$port ;
    > my @ndx = @$indx ;
    > my @spline = @$spl ;



    These latter three statements are OK if you actually want to make a copy
    of the three arrays in your sub. It is not necessary, and, if the
    purpose of your sub is to modify values in the arrays, won't work unless
    you copy the modified values back to the arrays before you return. You
    can instead access elements of the arrays as, for example:

    $$port[3]='something or other';
    @$indx[3..6]=(4..7);
    $val=$$spl[23];

    or you can use notation like:

    $port->[3]='something or other';

    etc if you prefer a "cleaner" implementation (at least according to some
    definition of "clean").


    >
    >
    > 2nd call:
    >
    > &printTset( \@indx, $vect, $cmmnt ) ;
    > }
    >
    > 2nd working sub:
    >
    > sub printTset {
    > my ( $indx, $vct, $cmt) = @_ ;
    > my @ndx = @$indx;
    > my $vect = $vct;
    > my $cmmnt = $cmt;



    Again, you don't have to make local copies of the data unless that is
    really what you want to do. In this case, passing the scalars directly
    is fine, since they will always have just a single value in @_.


    >
    > if i don't use the \ on the passed parameters, it seems to merge them
    > all into one big array.. blahh.



    Yep. That's the way Perl's argument calling semantics work. It's a
    feature, not a bug or problem :).


    >
    > this seems like a lot of code, seemingly redundant to my wee perl mind,
    > to pass values to a subroutine.



    Well, it isn't that much overhead when writing the code -- one extra $
    or @ for each time you want to reference an item. Plus don't forget you
    can also pass hashes, globs, and references (and maybe some other stuff
    I'm forgetting or don't know about) this way too. And of course, hashes
    of arrays of hashes, etc etc.


    >
    > what magic am i missing or is this just the way it is???



    Nope, that's the way it is. Except you shouldn't make local copies
    unless there is a good reason why.


    ....

    --
    Bob Walton

    --
    Bob Walton
     
    Bob Walton, Aug 15, 2003
    #2
    1. Advertising

  3. ktom wrote:
    >
    > I have to subs in which i am attempting to pass multiple args to and i
    > have managed to get it to work, after spending all afternoon trying to
    > get my brain around it. I still don't have my brain around and the
    > solution seems absurd!!
    >
    > below are snippets...
    >
    > 1st call:
    >
    > &printVec( \@spline, \@indx, \@port1 );
    > }
    >
    > 1st working sub:
    >
    > sub printVec {
    > #our @spline;
    > # my (@spline,@indx,@port) = @_ ;
    > # print "pre @$spl, @$indx, @$port\n";
    > # print "spline @spline\n";
    > my ($spl,$indx,$port) = @_ ;
    > my @prt = @$port ;
    > my @ndx = @$indx ;
    > my @spline = @$spl ;
    >
    > 2nd call:
    >
    > &printTset( \@indx, $vect, $cmmnt ) ;
    > }
    >
    > 2nd working sub:
    >
    > sub printTset {
    > my ( $indx, $vct, $cmt) = @_ ;
    > my @ndx = @$indx;
    > my $vect = $vct;
    > my $cmmnt = $cmt;
    >
    > if i don't use the \ on the passed parameters, it seems to merge them
    > all into one big array.. blahh.
    >
    > this seems like a lot of code, seemingly redundant to my wee perl mind,
    > to pass values to a subroutine.
    >
    > what magic am i missing or is this just the way it is???


    If you pass an array to a sub, you are actually
    passing a LIST of all the members of the array.

    Inside the sub, the code has no way to determine
    how many of the items in @_ are part of each array.
    If you only need to pass one array and some scalars,
    pass the scalars FIRST, then everything else is part
    of the array. To pass multiple arrays, you either
    pass references as you did with the \ or you must
    pass some indications so the sub can figure out
    how many items from @_ belong in each array. I
    think the references are the preferred/simplest
    method.

    Mike
     
    Michael P. Broida, Aug 15, 2003
    #3
  4. ktom

    ktom Guest

    Bob Walton wrote:
    > ktom wrote:
    >
    > > I have to subs in which i am attempting to pass multiple args to and i
    > > have managed to get it to work, after spending all afternoon trying to
    > > get my brain around it. I still don't have my brain around and the
    > > solution seems absurd!!
    > >
    > > below are snippets...
    > >
    > > 1st call:
    > >
    > > &printVec( \@spline, \@indx, \@port1 );

    >
    > ----------^
    >
    > Any more (that is, with Perl's less than many years old), you shouldn't
    > use the & in your call unless you actually want the specific
    > functionality it provides. See:
    >
    > perldoc perlsub
    >
    > for details.
    >
    >
    > > }
    > >
    > > 1st working sub:
    > >
    > > sub printVec {
    > > #our @spline;
    > > # my (@spline,@indx,@port) = @_ ;
    > > # print "pre @$spl, @$indx, @$port\n";
    > > # print "spline @spline\n";
    > > my ($spl,$indx,$port) = @_ ;
    > > my @prt = @$port ;
    > > my @ndx = @$indx ;
    > > my @spline = @$spl ;

    >
    >

    thanks for responding.. and to the others who responded..

    the main reason for the copy is to use a
    while( @array ){
    ..
    stuff
    ..
    shift @array
    }
    to loop through the items. i am guessing i could have accomplished the
    same thing with a for loop that didn't modify the array.

    i don't need to modify the values coming in.

    > These latter three statements are OK if you actually want to make a copy
    > of the three arrays in your sub. It is not necessary, and, if the
    > purpose of your sub is to modify values in the arrays, won't work unless
    > you copy the modified values back to the arrays before you return. You
    > can instead access elements of the arrays as, for example:
    >
    > $$port[3]='something or other';
    > @$indx[3..6]=(4..7);
    > $val=$$spl[23];
    >
    > or you can use notation like:
    >
    > $port->[3]='something or other';
    >
    > etc if you prefer a "cleaner" implementation (at least according to some
    > definition of "clean").
    >
    >
    > >
    > >
    > > 2nd call:
    > >
    > > &printTset( \@indx, $vect, $cmmnt ) ;
    > > }
    > >
    > > 2nd working sub:
    > >
    > > sub printTset {
    > > my ( $indx, $vct, $cmt) = @_ ;
    > > my @ndx = @$indx;
    > > my $vect = $vct;
    > > my $cmmnt = $cmt;

    >
    >
    > Again, you don't have to make local copies of the data unless that is
    > really what you want to do. In this case, passing the scalars directly
    > is fine, since they will always have just a single value in @_.
    >
    >
    > >
    > > if i don't use the \ on the passed parameters, it seems to merge them
    > > all into one big array.. blahh.

    >
    >
    > Yep. That's the way Perl's argument calling semantics work. It's a
    > feature, not a bug or problem :).
    >
    >
    > >
    > > this seems like a lot of code, seemingly redundant to my wee perl mind,
    > > to pass values to a subroutine.

    >
    >
    > Well, it isn't that much overhead when writing the code -- one extra $
    > or @ for each time you want to reference an item. Plus don't forget you
    > can also pass hashes, globs, and references (and maybe some other stuff
    > I'm forgetting or don't know about) this way too. And of course, hashes
    > of arrays of hashes, etc etc.
    >
    >
    > >
    > > what magic am i missing or is this just the way it is???

    >
    >
    > Nope, that's the way it is. Except you shouldn't make local copies
    > unless there is a good reason why.
    >
    >
    > ...
    >
     
    ktom, Aug 15, 2003
    #4
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Ken Varn
    Replies:
    2
    Views:
    643
    Ken Varn
    Jun 22, 2005
  2. Replies:
    3
    Views:
    506
    David Eppstein
    Sep 17, 2003
  3. Pierre Fortin

    args v. *args passed to: os.path.join()

    Pierre Fortin, Sep 18, 2004, in forum: Python
    Replies:
    2
    Views:
    710
    Pierre Fortin
    Sep 18, 2004
  4. Ben
    Replies:
    2
    Views:
    919
  5. Lawrence D'Oliveiro

    Death To Sub-Sub-Sub-Directories!

    Lawrence D'Oliveiro, May 5, 2011, in forum: Java
    Replies:
    92
    Views:
    2,083
    Lawrence D'Oliveiro
    May 20, 2011
Loading...

Share This Page