subroutines intermediate

How to pass arrays to subroutines without flattening in Perl?

Question

How to pass arrays to subroutines without flattening in Perl?

In Perl, subroutine arguments are always received as a single flat list in @_. When you pass multiple arrays to a subroutine directly, Perl concatenates them, losing the boundaries between arrays. The standard solution is to pass references to arrays instead of the arrays themselves.

Why Arrays Flatten

When you call a subroutine with multiple arrays, Perl flattens them into one list. Inside the subroutine, @_ contains all elements in sequence with no way to distinguish where one array ends and another begins.

Solution: Pass Array References

By passing references using the backslash operator \@array, you provide scalar pointers to the arrays. The subroutine receives distinct scalar references that can be dereferenced to access the original arrays.

Complete Runnable Example

#!/usr/bin/perl
use strict;
use warnings;

# Subroutine expects two array references
sub print_arrays {
    my ($arr1_ref, $arr2_ref) = @_;
    
    # Dereference to access array elements
    print "Array 1: ", join(", ", @{$arr1_ref}), "\n";
    print "Array 2: ", join(", ", @{$arr2_ref}), "\n";
}

my @array1 = (1, 2, 3);
my @array2 = ('a', 'b', 'c');

# Pass references to avoid flattening
print_arrays(\@array1, \@array2);

Key Concepts

  • \@array creates a reference (scalar) to an array
  • @{$ref} dereferences back to the array
  • References preserve array boundaries since they're scalar values
  • Works in all Perl 5 versions

Common Pitfalls

  • Trying my (@a, @b) = @_; doesn't work—@a consumes all of @_ in list context
  • Forgetting to dereference prints memory addresses instead of contents
  • Passing arrays directly loses the ability to distinguish between them

This reference-based approach is the idiomatic Perl solution (part of TMTOWTDI) and is essential for writing maintainable code that handles multiple arrays cleanly.

Verified Code

Executed in a sandbox to capture real output. • v5.34.1 • 8ms

Tip: edit code and use “Run (Browser)”. Server runs always execute the published, verified snippet.
STDOUT
Array 1: 1, 2, 3
Array 2: a, b, c
STDERR
(empty)

Was this helpful?

Related Questions