http://qs321.pair.com?node_id=11119273

davido has asked for the wisdom of the Perl Monks concerning the following question:

perlsub states the following:

When using a signature, the arguments are still available in the special array variable @_ , in addition to the lexical variables of the signature.

We can confirm this:

sub baz ($this, $that) { warn '@_ contains ', scalar(@_), " elements.\n"; } baz('hello', 'world') # @_ contains 2 elements.

But what happens when one of the parameters is optional?

sub foo ($this, $that = 'world') { warn '@_ contains ', scalar(@_), " elements.\n"; } foo('hello'); # @_ contains 1 elements.

Here's an example with tests:

#!/usr/bin/env perl use strict; use warnings; use feature qw(signatures); no warnings qw(experimental::signatures); use Test::More tests => 8; sub baz($this, $that) { ok defined($this), "\$this is defined and contains $this"; ok defined($that), "\$that is defined and contains $that"; is scalar(@_), 2, '@_ has two elements.'; is_deeply \@_, [$this, $that] or diag 'Parameters: ', explain { this => $this, that => $that, at_underscore => \@_ }; } sub foo ($this, $that='bar') { ok defined($this), "\$this is defined and contains $this"; is $that, 'bar', '\$that contains "bar"'; is scalar(@_), 2, '@_ has two elements.'; is_deeply \@_, [$this, $that] or diag 'Parameters: ', explain { this => $this, that => $that, at_underscore => \@_ }; } note "\n\nTesting baz()"; baz('hello', 'world'); note "\n\nTesting foo()"; foo("a");

The output is...

1..8 # # # Testing baz() ok 1 - $this is defined and contains hello ok 2 - $that is defined and contains world ok 3 - @_ has two elements. ok 4 # # # Testing foo() ok 5 - $this is defined and contains a ok 6 - \$that contains "bar" not ok 7 - @_ has two elements. # Failed test '@_ has two elements.' # at mytest2.pl line 24. # got: '1' # expected: '2' not ok 8 # Failed test at mytest2.pl line 25. # Structures begin differing at: # $got->[1] = Does not exist # $expected->[1] = 'bar' # Parameters: { # 'at_underscore' => [ # 'a' # ], # 'that' => 'bar', # 'this' => 'a' # } # Looks like you failed 2 tests of 8. shell returned 2

This has probably been discussed a lot somewhere.

The question: Is the reason that scalar(@_) does not contain aliases to optional values so that we can determine how many parameters were actually passed, and if so, should it be documented?


Dave