http://www.perlmonks.org?node_id=11124930


in reply to Re: Length of Array Passed as Reference
in thread Length of Array Passed as Reference

Engaging beancounter mode ... - ready.

sub test_function { my $ref = shift; # this function takes one argument, a ref to a +n ARRAY # Note: you could do extra manual checking of function arguments. # Not necessarily recommended: shown for educational purposes. defined($ref) or die "oops: you did not pass any arguments"; @_ and die "oops: this function takes exactly one argument";

There is an edge case where this code produces a wrong error message:

use strict; use warnings; use feature 'say'; sub test_function { my $ref = shift; # this function takes one argument, a ref to a +n ARRAY # Note: you could do extra manual checking of function arguments. # Not necessarily recommended: shown for educational purposes. defined($ref) or die "oops: you did not pass any arguments"; @_ and die "oops: this function takes exactly one argument"; } say "Calling test_function with no arguments:"; eval { test_function(); }; say $@; say "Calling test_function with a single undefined argument:"; eval { test_function(undef); }; say $@;
X:\>perl foo.pl Calling test_function with no arguments: oops: you did not pass any arguments at foo.pl line 10. Calling test_function with a single undefined argument: oops: you did not pass any arguments at foo.pl line 10. X:\>

Generally, the error messages are slightly confusing: They report the line where the error was detected, not where the error was made. Carp can help:

use strict; use warnings; use feature 'say'; use Carp qw( croak ); sub test_function { @_==1 or croak "oops: this function takes exactly one argument"; my $ref = shift; # this function takes one argument, a ref to a +n ARRAY # Note: you could do extra manual checking of function arguments. # Not necessarily recommended: shown for educational purposes. defined($ref) or croak "oops: argument is not defined"; } say "Calling test_function with no arguments:"; eval { test_function(); }; say $@; say "Calling test_function with an undefined argument:"; eval { test_function(undef); }; say $@;
X:\>perl foo.pl Calling test_function with no arguments: oops: this function takes exactly one argument at foo.pl line 7 main::test_function() called at foo.pl line 17 eval {...} called at foo.pl line 16 Calling test_function with an undefined argument: oops: argument is not defined at foo.pl line 12 main::test_function(undef) called at foo.pl line 23 eval {...} called at foo.pl line 22 X:\>

Doing the same without the stack trace takes a little bit more work.

Alexander

--
Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so". ;-)