Tweet

How do I return multiple variables from a subroutine?

The problem

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.

Returning two arrays

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.

Returning two hashes

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.

Revision: 1.5 [Top]