XP is just a number PerlMonks

### Parameters, subs and the shift function

by Foggy Bottoms (Monk)
 on Aug 19, 2003 at 11:04 UTC Need Help??

Foggy Bottoms has asked for the wisdom of the Perl Monks concerning the following question:

Dearest monks of far and wide,

As you may know when one writes a sub, he/she can send parameters to that sub and one of the most convenient ways to retrieve those parameters is by using the tool shift...

One question has been puzzling me however... Let's take for example the following sub :
```sub test
{
my \$number = shift;
my @array1 = shift;
my @array2 = shift;
}
........................
my @b = ("London","Bridge","is");
# call sub
test(3,@a,@b);
How does the sub manage to figure out what's the size of @a and @b so that when you use the shift tool you don't end up with @array1 being ("mary","had","a","little","lamb","!","London","Bridge","is"); and @array2 nothing...

Surely this is a trivial question and I'm probably overlooking something important - but I'm still quite intrigued. Could someone please enlighten me ?

Replies are listed 'Best First'.
Re: Parameters, subs and the shift function
by Abigail-II (Bishop) on Aug 19, 2003 at 11:08 UTC
Parameters to a function get flattened to a single list. If you call a sub as test (3, @a, @b), then inside test you can't distinguish what came from @a and what from @b. If you want to pass entire arrays, you will have to pass references, and deal with references in the function.
```    sub test {
my \$number = shift;
my @array1 = @{+shift};  # Shift off the reference, and derefe
+rence it
my @array2 = @{+shift};
}
test (2, \@a, \@b);

Abigail

Abagail-II, what is the signifigance of the + in the shift statements? Why is this a good thing to do?
```my @array1 = @{+shift};
my @array2 = @{+shift};
Thanks,
Tim
Run it under strict, and try it without the +. The error message you get will enlighten you.

Abigail

Re: Parameters, subs and the shift function
by edan (Curate) on Aug 19, 2003 at 11:15 UTC

You went to the trouble of writing some nice test code, but did you run it? It might help answer some of your questions...

First, shift only takes one element off the parameter list, so your test sub will give you:

```\$number = 3;
@array1 = ("mary");

As for how the arguments are passed to the function, perl flattens out the argument list, so it will arrive as one big list (@_ to be exact), and you won't be able to tell where one list end and another begins. If you need to do this, you'll have to pass references, like so:

```sub test
{
my \$number = shift;
my \$arrayref1 = shift;
my \$arrayref2 = shift;
# remember to dereference: @\$arrayref1 etc.
}
# .........
my @b = ("London","Bridge","is");
# call sub
test(3,\@a,\@b);

HTH

--
3dan
Re: Parameters, subs and the shift function
by larsen (Parson) on Aug 19, 2003 at 11:08 UTC
How does the sub manage to figure out what's the size of @a and @b so that when you use the shift tool you don't end up with @array1 being ("mary","had","a","little","lamb","!","London","Bridge","is"); and @array2 nothing...
No way. See "Pass by reference" in perlsub.
Re: Parameters, subs and the shift function
by CombatSquirrel (Hermit) on Aug 19, 2003 at 12:16 UTC
Just one thing to add to what the others said: Although discouraged by some, I personally fancy prototypes. In the following example prototyping the function makes it seem (this "seem" is important) as if you just needed arrays and not references to arrays; the references are automatically generated by Perl.
```#!perl

use strict;
use warnings;

sub test (\$\@\@) {
my \$number = shift;
my @array1 = @{+shift};  # Shift off the reference, and dereference
+ it
my @array2 = @{+shift};
# Print the variable contents
print \$number . \$/ . join(' - ', @array1) . \$/ . join(' - ', @array
+2) . \$/;
}
my @a = qw(mary had a little lamb !);
my @b = qw(London Bridge is);
test (2, @a, @b);
__END__
OUTPUT:
2
mary - had - a - little - lamb - !
London - Bridge - is
Have a look at perlsub for an explanation of prototypes. Please note that the above only works for arrays and not for lists.
Hope this helped.
Re: Parameters, subs and the shift function
by davorg (Chancellor) on Aug 19, 2003 at 14:13 UTC
How does the sub manage to figure out what's the size of @a and @b

It doesn't

Update: Yes, as 3dan points out below, there was some incorrect nonsense in this node for about 30 seconds after I posted it. When I realised my error I removed it immediately. Sorry for any confusion caused.

--
<http://www.dave.org.uk>

"The first rule of Perl club is you do not talk about Perl club."
-- Chip Salzenberg

Update: This node is in response to davorg's post, which he has subsequently updated by removing the offending material, so this response as well as the response of Foggy Bottoms becomes garbage. I think in the future, davorg, you should strike out or otherwise update your node, instead of just deleting material that people have already related to.

so that when you use the shift tool you don't end up with @array1 being "mary","had","a","little","lamb","!","London","Bridge","is"); and @array2 nothing...

With your code, that's exactly what would happen.

No, you're wrong. shift returns the first value in the flattened argument list each time it is called, and removes it, so @array1 will be ("mary"), and @array2 will be ("had"). If the code would have been written like this:

```my (\$number, @array1, @array2) = @_;

... then you'd be right.

--
3dan
That's not what I understand from what 3dan said, so I'm a bit puzzled. Anyway, I updated my code and the arrays work fine now (cuz I actually had the problem but since I hadn't bothered printing out @array1 and @array2 I hadn't noticed the error, not until I felt the urge to satisfy my curiosity and ask the question here...)
Thanks

Create A New User
Node Status?
node history
Node Type: perlquestion [id://284847]
Approved by broquaint
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others avoiding work at the Monastery: (9)
As of 2019-10-14 22:41 GMT
Sections?
Information?
Find Nodes?
Leftovers?
Voting Booth?
In 2019 the site I miss most is:

Results (36 votes). Check out past polls.

Notices?