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. Usescalar @_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
undefbeing passed and fewer arguments. Bothfunc(undef)and checking beyond array bounds giveundef.
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
Hello, John Doe!
Sum: 50
User: alice (alice@example.com) - Role: user
User: bob (bob@example.com) - Role: admin
(empty)Was this helpful?
Related Questions
- How to use the return statement early in a Perl subroutine?
- How to create higher-order functions in Perl?
- How to use shift to get subroutine arguments in Perl?
- How to use caller() to get subroutine call information in Perl?
- How to call a subroutine as a method in Perl?
- How to use state variables in Perl subroutines?