Re: passing an array
by Masem (Monsignor) on Mar 28, 2001 at 07:32 UTC
|
Use references (see perlref). For example...
my @data = qw( Mon Tue Wed Thurs Fri Sat Sun );
print get_day( $today, \@data );
sub get_day
{
my ( $index, $datar ) = @_;
return $datar->[$index];
}
Update: You know, it helps to have a @_ in a sub too :-/
Dr. Michael K. Neylon - mneylon-pm@masemware.com
||
"You've left the lens cap of your mind on again, Pinky" - The Brain
| [reply] [d/l] |
(Ovid - prototypes?) Re: passing an array
by Ovid (Cardinal) on Mar 28, 2001 at 12:15 UTC
|
Also, you could consider using prototypes:
use warnings;
use strict;
sub multipop(\@$);
my @array = (1 .. 10);
my @result = multipop @array, 3;
print "@array\n";
print "@result\n";
sub multipop(\@$) {
my $count = pop;
my @vars;
$count = 1 if ! defined $count; # default to normal pop behavior
if ( $count =~ /^\d+$/ ) {
my $length = scalar @{$_[0]};
$count = $length if $count > $length;
# Using @{$_[0]} to ensure that we modify original array
push @vars, splice ( @{$_[0]}, -$count, $count ) if $count > 0
+;
return @vars;
} else {
warn "Second argument to multipop must be numeric: '$count'";
}
}
Notice the sub call:
my @result = multipop @array, 3;
Yup, you're passing an array to it, but Perl converts it to a reference to the array. Pretty handy, huh? You may want to read this discussion of prototypes and their limitations
And yeah, that code above is a bit of a hack. If anyone sees problems with it, I'd love to know. It's basically the same thing as pop, but with an optional second argument specifying the number of elements to remove. It could be expanded to take a third argument specifying if the order of elements to remove is to be reversed. It does have a couple of advantages over splice (IMHO): it's easier to read and will not die if you try to pop more elements than the array has. Of course, some may not appreciate the latter "feature".
Oh, and it's slower than splice, too :)
Cheers,
Ovid
Update: Ugh! Stupid me. No third argument. Just make the second one negative for a reverse pop (and add the appropriate code, of course). Sheesh. I try to make things too hard, at times :)
Join the Perlmonks Setiathome Group or just click on the the link and check out our stats. | [reply] [d/l] [select] |
|
|
| [reply] |
Re: passing an array
by Xxaxx (Monk) on Mar 28, 2001 at 07:19 UTC
|
sub doStuff
{
my($arg1, $arg2, $arg3, $ar4, @data) = @_;
..... # other stuff here
}
That will get the data in.
I'm curious to see about better
answers. I've been wondering about shift and other such
alternate forms recently since I've noticed code examples
using that form.
Meanwhile this should get the the array.
Now if your array were huge (not the two element array mentioned here)
then passing by reference might be the way to go.
But I figure if you're scaling the challenge of just
getting data in, there's no point throwing variables by reference at you just yet.
But do bookmark the thought it can be useful.
HTH
Claude
p.s.
my($arg1, $arg2, $arg3, $ar4, @data, $arg5) = @_;
will not work. The @data will suck up all the vars
leaving nothing in $arg5. Just a warning from someone who
didn't know this at 3 a.m.
| [reply] [d/l] [select] |
|
|
I use shift and references like in the following example. Hope this helps.
Roberto
#!/usr/bin/perl
use strict;
my %hash;
my @array;
# here you pass the references and get them back
my ($ref_hash,$ref_array) = load_variables(\%hash,\@array);
# and then you pass these for printout
print_variables($ref_hash,$ref_array);
##################
sub load_variables {
##################
my %hash1 = %{ shift() };
my @array1 = @{ shift() };
### Load array
@array1 = ('a','b','c');
### Populate the hash (for each character
### set the hash to the next
map {
my $tmp = ++$_;
$hash1{$_} = qq($tmp);
} @array1;
### Return the references
return (\%hash1,\@array1);
}
###################
sub print_variables {
###################
my %hash2 = %{ shift() };
my @array2 = @{ shift() };
map { printf q(hash: ).qq($hash2{$_}\n) } keys %hash2;
}
| [reply] [d/l] |
Re: passing an array
by the_slycer (Chaplain) on Mar 28, 2001 at 08:10 UTC
|
Just to expand on the above answers. In your example you pass
arg1, $arg2, $arg3, $ar4, @data to the sub. What @_ gets is
$_[0] = $arg1,
$_[1] = $arg2,
$_[2] = $arg3,
$_[3] = $arg4,
$_[4] = $data[0],
$_[5] = $data[1]
So you can see by the above what is happening.
The ways to do this are as mentioned above, pass a
reference to the array and dereference it, or assign all of the arguments to variables and
then assign the rest of the @_ array to @info..
Update: per merlyn's comments below, have updated appropriately. Normally I would have written it like that, really not sure why I didn't in this case. | [reply] [d/l] |
|
|
Ouch. Please. @foo[0] hurts my eyes.
Surely you meant to say:
$_[0] = $arg1,
$_[1] = $arg2,
$_[2] = $arg3,
$_[3] = $arg4,
$_[4] = $data[0],
$_[5] = $data[1]
A single-element slice is almost never what people want.
Warnings-on would have told you that.
-- Randal L. Schwartz, Perl hacker | [reply] [d/l] [select] |
Re: passing an array
by stephen (Priest) on Mar 28, 2001 at 07:58 UTC
|
sub doStuff
{
@info = @_;
print "@info";
}
That will copy everything that you passed to &doStuff into @info.
stephen
| [reply] [d/l] |
Re (tilly) 1: passing an array
by tilly (Archbishop) on Mar 28, 2001 at 10:09 UTC
|
Please use CODE tags rather than doing your layout.
Among other advantages is that there will be a d/l link
that people can use to get your code directly so they
can test it... | [reply] |
Re: passing an array
by ProfessorHaroldHill (Initiate) on Mar 28, 2001 at 18:36 UTC
|
Perl treats everything passed as scalar, so as the good
brothers before me agree use a reference
$array = \@array;
pass_this($anythingelse,$array);
sub pass_this(){
my($firstpassedthing,$array_ref) = (@_);
@local_array = @{$array_ref};
# now you can play with $local_array[]
}
The sadder but wiser Perl for me ...
Edit: chipmunk 2001-03-30 | [reply] [d/l] |
Re: passing an array
by tame1 (Pilgrim) on Mar 28, 2001 at 19:55 UTC
|
Given the tedious nature of stripping @_, perhaps using references would
make your life easier. That way you could use -> notation, or
break the ref back into an array, etc. Either way, it's gotta be
better that manually setting things with my $var = $_[0], etc.
What does this little button do . .<Click>;
"USER HAS SIGNED OFF FOR THE DAY" | [reply] [d/l] [select] |