subroutines intermediate

How to check the number of arguments passed to a subroutine in Perl?

Question

How to check the number of arguments passed to a subroutine in Perl?

In Perl, subroutines receive their arguments through the special array @_. To check the number of arguments passed to a subroutine, you can use scalar @_ or the shorthand @_ in scalar context. This is essential for validating input and preventing logic errors.

The most common approach is to check the size of @_ at the beginning of your subroutine and handle incorrect argument counts appropriately, either by returning early, dying with an error, or providing default values.

Basic Argument Counting

Here's a comprehensive example demonstrating various ways to check argument counts:

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

# Example 1: Exact count validation
sub greet_person {
    my $arg_count = scalar @_;
    die "Error: greet_person expects exactly 2 arguments, got $arg_count\n" 
        unless $arg_count == 2;
    
    my ($first_name, $last_name) = @_;
    return "Hello, $first_name $last_name!";
}

# Example 2: Minimum argument check
sub calculate_sum {
    die "Error: calculate_sum needs at least 1 argument\n" if @_ < 1;
    
    my $sum = 0;
    $sum += $_ for @_;
    return $sum;
}

# Example 3: Range validation
sub create_user {
    my $count = @_;  # scalar context
    die "Error: create_user expects 2-3 arguments, got $count\n" 
        unless $count >= 2 && $count <= 3;
    
    my ($username, $email, $role) = @_;
    $role //= 'user';  # default value if not provided (Perl 5.10+)
    return "User: $username ($email) - Role: $role";
}

# Test the subroutines
print greet_person("John", "Doe"), "\n";
print "Sum: ", calculate_sum(5, 10, 15, 20), "\n";
print create_user("alice", "alice\@example.com"), "\n";
print create_user("bob", "bob\@example.com", "admin"), "\n";

# This would die: greet_person("Only one arg");

Common Pitfalls

  • List vs Scalar Context: In list context, @_ returns all elements. Use scalar @_ or just @_ in scalar context (like numeric comparisons) to get the count.
  • Modifying @_: Remember that @_ contains aliases to the original arguments. Modifying $_[0] directly changes the caller's variable.
  • Undef vs Missing: Perl doesn't distinguish between undef being passed and fewer arguments. Both func(undef) and checking beyond array bounds give undef.

For Perl 5.20+, you can use subroutine signatures with use feature 'signatures' for automatic argument validation, though this is still considered experimental in some versions.

Verified Code

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

Tip: edit code and use “Run (Browser)”. Server runs always execute the published, verified snippet.
STDOUT
Hello, John Doe!
Sum: 50
User: alice (alice@example.com) - Role: user
User: bob (bob@example.com) - Role: admin
STDERR
(empty)

Was this helpful?

Related Questions