question regarding multiple args to sub

K

ktom

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..
 
B

Bob Walton

ktom said:
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.


....
 
M

Michael P. Broida

ktom said:
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
 
K

ktom

Bob said:
----------^

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.
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.


...
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top