LinuxQuestions.org
Visit Jeremy's Blog.
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices

Reply
 
Search this Thread
Old 04-18-2005, 09:58 AM   #1
johnMG
Member
 
Registered: Jul 2003
Location: CT, USA
Distribution: Debian Sarge (server), Etch (work/home)
Posts: 601

Rep: Reputation: 31
perl: passing 2 individual arrays/lists as args


Suppose I'm writing a function that I want to operate on two different arrays:

Code:
#!/usr/bin/perl

use warnings;
use strict;

my @a = ( 1, 2, 3 ); 
my @b = qw/ foo bar /;

sub do_something_with_two_arrays
{
      my (@a1, @a2) = @_; # ? XXX 
      print "In the first array arg passed, we have:\n";
      for ( @a1 ) { print "$_\n"; }
      print "And in the second array arg passed:\n";
      for ( @a2 ) { print "$_\n"; }
      # Maybe some processing follows...
}

print "-" x 40, "\n";
do_something_with_two_arrays @a, @b; 
print "~" x 40, "\n";
do_something_with_two_arrays( @a, @b ); # Nope. Same as above.
print "=" x 40, "\n";
How does Perl know where the first array ends and the next one begins?

I'm looking at the docs for the built-in 'push' function. It says that operator takes an ARRAY and then also a LIST. What's the difference? How does push know where the first one ends and the next one begins?
 
Old 04-18-2005, 10:05 AM   #2
johnMG
Member
 
Registered: Jul 2003
Location: CT, USA
Distribution: Debian Sarge (server), Etch (work/home)
Posts: 601

Original Poster
Rep: Reputation: 31
BTW, I realize that I can just use references to arrays to do what I want to do, however, I'd like to understand how builtins like 'push' do their magic.
 
Old 04-18-2005, 11:51 AM   #3
aluser
Member
 
Registered: Mar 2004
Location: Massachusetts
Distribution: Debian
Posts: 557

Rep: Reputation: 42
IIRC, you can do
Code:
sub foo (@@) {
    my ($ref1, $ref2) = @_;
    ....
}

foo(@array1, @array2);
The only problem with this is that in some situations it's possible to compile the code which calls foo before compiling foo itself, in which case the calling code won't know about the (@@) business and so will just pass a flat array. Of course, the perl builtins are guaranteed to be compiled before any code that uses them.
 
Old 04-18-2005, 12:53 PM   #4
sirclif
Member
 
Registered: Sep 2004
Location: south texas
Distribution: fedora core 3,4; gentoo
Posts: 192

Rep: Reputation: 30
perl doesn't know where one ends and the other begins. I believe the solution is to use references. the fact that perl throws all of it's subroutine arguments into one big list is handy most of the time, unless your dealing with arrays. So what you would do is create references to the arrays (kind of like pointers) and pass the references to the sub, then dereference them in the sub. for example:

Code:
#!/usr/bin/perl

use warnings;
use strict;

my @a = ( 1, 2, 3 ); 
my @b = qw/ foo bar /;

$a_ref = \@a;
$b_ref = \@b;


do_something_with_two_arrays($a_ref, $b_ref); 

do_something_with_two_arrays($b_ref, $a_ref);


sub do_something_with_two_arrays
{
      my ($a1_ref, $a2_ref) = @_; 
      print "In the first array arg passed, we have:\n";
      for ( @$a1_ref ) { print "$_\n"; }
      print "And in the second array arg passed:\n";
      for ( @$a2_ref ) { print "$_\n"; }
      # Maybe some processing follows...
}
the \ operator creates a reference, in this case to an array (@). a reference is a scalar data. to dereference a reference, just put the appropieate symbol in front of the reference name. e.i.

scalar: $$ref
array: @$ref
hash: %$ref

hope this helps
 
Old 04-18-2005, 12:57 PM   #5
johnMG
Member
 
Registered: Jul 2003
Location: CT, USA
Distribution: Debian Sarge (server), Etch (work/home)
Posts: 601

Original Poster
Rep: Reputation: 31
Ahh... that (@@) function declaration notation seems to be what I was missing. I'll look further into it. Thanks.
 
Old 04-18-2005, 01:20 PM   #6
johnMG
Member
 
Registered: Jul 2003
Location: CT, USA
Distribution: Debian Sarge (server), Etch (work/home)
Posts: 601

Original Poster
Rep: Reputation: 31
Thanks sirclif. I've also found "man perlreftut" and, of course, "man perlref" pretty helpful as well.
 
Old 04-18-2005, 01:27 PM   #7
sirclif
Member
 
Registered: Sep 2004
Location: south texas
Distribution: fedora core 3,4; gentoo
Posts: 192

Rep: Reputation: 30
sorry i didn't see your replay saying that you already knew about references. the built in function push takes an array and 'tacks on' a scalar value or a list to the end of the array. there isn't much difference between an array and a list. an array is just a list with a name really. anyhow, given an array array1 you can push and pop elements on and off.

@array1 = (1,2,3);
push @array1, 4;

array1 now looks like (1,2,3,4)

vise versa if you pop the array into a scalar

$tmp = pop @array1;

tmp is now 4. but again, push, pop, unshift, and shift have no idea that an array is supposed to be more than one array, they just add and remove elements from the back and front of an array.
 
Old 04-18-2005, 02:05 PM   #8
johnMG
Member
 
Registered: Jul 2003
Location: CT, USA
Distribution: Debian Sarge (server), Etch (work/home)
Posts: 601

Original Poster
Rep: Reputation: 31
> but again, push, pop, unshift, and shift have no idea that an
> array is supposed to be more than one array, they just add
> and remove elements from the back and front of an array.

Yes, but there's magic going on there. "push", of course, *modifies* @array1. If the args passed to "push" were all simply flattened into one list, there would be no way for "push" to know about the array it was supposed to modify. This is why it seems (to me) like "(@@)" is key. Looks like "man perlsub" explains it under the heading "Prototypes" (which I'm currently having a look at :).

Thanks.

Last edited by johnMG; 04-18-2005 at 02:08 PM.
 
Old 04-18-2005, 02:16 PM   #9
sirclif
Member
 
Registered: Sep 2004
Location: south texas
Distribution: fedora core 3,4; gentoo
Posts: 192

Rep: Reputation: 30
ah, i see what your saying. the builtin function push takes two arrays and still knows how to deal with it. buitins also do not require parentheses around thier arguments, or the & operator.
 
Old 04-18-2005, 02:39 PM   #10
aluser
Member
 
Registered: Mar 2004
Location: Massachusetts
Distribution: Debian
Posts: 557

Rep: Reputation: 42
Quote:
buitins also do not require parentheses around thier arguments, or the & operator.
Actually, user functions don't either : )
Code:
15:38 aluser@alf:~$ perl -e 'sub foo { print "hi there $_[0]\n" } foo "bob"'
hi there bob
 
Old 04-18-2005, 03:12 PM   #11
puffinman
Member
 
Registered: Jan 2005
Location: Atlanta, GA
Distribution: Gentoo, Slackware
Posts: 217

Rep: Reputation: 30
Quote:
Actually, user functions don't either : )
Not having to use the & operator is only true if the subroutine is defined before it is used.
 
Old 04-18-2005, 03:13 PM   #12
sirclif
Member
 
Registered: Sep 2004
Location: south texas
Distribution: fedora core 3,4; gentoo
Posts: 192

Rep: Reputation: 30
wow, sure enought.
why can't i get it to work in a script file?
 
Old 04-18-2005, 03:49 PM   #13
aluser
Member
 
Registered: Mar 2004
Location: Massachusetts
Distribution: Debian
Posts: 557

Rep: Reputation: 42
Quote:
why can't i get it to work in a script file?
Evidently you do need the parenthesis if you have the declaration of the sub after its use. This works:
Code:
#!/usr/bin/perl
use strict;
use warnings;

foo("bob");

sub foo {
        print "hi there $_[0]\n";
}
I'm not aware of any case where the & is required in a call to the function; I use it to take references and that's about it. Of course, it's a matter of style.

For user functions, I tend to always use parentheses; probably because I've had that error from not predeclaring the sub at some point and mostly because it makes things less clear not to have them.
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Linked Lists vs Arrays in OS develpment NCC-1701&NCC-1701-D Programming 5 08-02-2005 12:03 PM
perl: concatenate arrays jrtayloriv Programming 2 01-23-2005 07:13 AM
PERL : Arrays confusing? fredgt Programming 3 12-19-2004 08:24 AM
dereferencing anonymous arrays in Perl coolman0stress Programming 6 10-27-2003 10:17 PM
arrays in perl BBQ_Matt Programming 3 09-23-2003 07:45 AM


All times are GMT -5. The time now is 01:51 PM.

Main Menu
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
identi.ca: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration