Home » Faqs » Perl thinking » Returning |
Often you'll want to return more than one variable from a subroutine. You could do this by returning all the values in an array, or by accepting variable references as parameters and modifying those.
In Perl however, you can return multiple variables easily.
Getting one variable back:
#!/usr/bin/perl use strict; use warnings; # Subroutine prototypes sub get_one(); # Get one variable back my $one = get_one(); print "One: $one\n"; sub get_one() { return "one"; }
The output you should see is:
One: one
Getting two variables back:
#!/usr/bin/perl use strict; use warnings; # Subroutine prototypes sub get_two_arrays(); # Get two variables back my ($one, $two) = get_two(); print "One: $one\n"; print "Two: $two\n"; sub get_two() { return ("one", "two"); }
The output you should see is:
One: one Two: two
You can of course return more than two variables. Just follow the syntax above and add more variables.
While this works fine for scalar variables. When you start playing with arrays and hashes you need to be careful.
For example, the following code may not quite do what you would think:
#!/usr/bin/perl use strict; use warnings; # Subroutine prototypes sub get_two_arrays(); # Get two variables back my (@one, @two) = get_two_arrays(); print "First: @one\n"; print "Second: @two\n"; sub get_two_arrays() { my @array1 = ("a", "b", "c", "d"); my @array2 = (1, 2, 3, 4); return (@array1, @array2); }
The output of this program is:
First: a b c d 1 2 3 4 Second:
All of the data has been put into the first array! This is because all of the values are returned in a single big array, and then perl doesn't know how to put that into two arrays, so it puts it all in the first one.
For this example to work properly, you'd need to return array references:
#!/usr/bin/perl use strict; use warnings; # Subroutine prototypes sub get_two_arrays(); # Get two variables back my ($one_ref, $two_ref) = get_two_arrays(); my @one = @$one_ref; my @two = @$two_ref; print "First: @one\n"; print "Second: @two\n"; sub get_two_arrays() { my @array1 = ("a", "b", "c", "d"); my @array2 = (1, 2, 3, 4); return (\@array1, \@array2); }
This has the output that you would expect:
First: a b c d Second: 1 2 3 4
In this case two references are returned into two scalar variables, so perl can work it out perfectly.
Often it is better to return references than arrays (or hashes) anyway. Imagine if you have a very large array. Returning it directly means that an entire copy of the array is made into another part of memory. However, if you return a reference to the array, the hugh array stays where it is and a reference to the array is copied around. Much better memory usage.
Hashes have the same problem. We won't go into it in detail here but a hash can very easily turn into an array:
#!/usr/bin/perl use strict; use warnings; my %hash = (name => 'bob', age => '78'); my @array = %hash; print "@array\n";
Would give the following output:
age 78 name bob
So if you were to return two hashes from a subroutine, like with arrays, all the data would end up in the first hash:
#!/usr/bin/perl use strict; use warnings; # Subroutine prototypes sub get_two_hashes(); # Get two variables back my (%one, %two) = get_two_hashes(); print "One: "; print "$_ " foreach keys %one; print "\n"; print "Two: "; print "$_ " foreach keys %two; print "\n"; sub get_two_hashes() { my %hash1 = ( "1a" => "b", "1b" => "d" ); my %hash2 = ( "2a" => 2, "2b" => 4 ); return (%hash1, %hash2); }
This has the following output:
One: 1b 2a 2b 1a Two:
Like arrays, use references instead:
#!/usr/bin/perl use strict; use warnings; # Subroutine prototypes sub get_two_hashes(); # Get two variables back my ($one, $two) = get_two_hashes(); print "One: "; print "$_ " foreach keys %$one; print "\n"; print "Two: "; print "$_ " foreach keys %$two; print "\n"; sub get_two_hashes() { my %hash1 = ( "1a" => "b", "1b" => "d" ); my %hash2 = ( "2a" => 2, "2b" => 4 ); return (\%hash1, \%hash2); }
Output is:
One: 1b 1a Two: 2a 2b
Just like arrays, returning references rather than the actual hash is much better memory usage.