#!/usr/bin/perl use v5.12; use Test2::V0; use experimental 'signatures'; sub show ($arg) { defined $arg ? $arg : 'undef'; } # No signature, no check. sub no_sig { my $what = shift; state $data; # Straight forward: shift off first arg if there is any. if (@_) { my $arg = shift; say "$what: ", show $arg; $data = $arg; } else { say "$what: ", show $data; return $data; } } # Standard signature with optional second arg. sub sig_std ($what, $arg=undef) { state $data; # Kind of illogical: there is no obvious connection between @_, its # size and $arg. if (@_ >= 2) { say "$what: ", show $arg; $data = $arg; } else { say "$what: ", show $data; return $data; } } # Signature with side effect on missing arg. sub sig_lexical ($what, $arg=(my $no_arg=1, undef)) { state $data; # $arg and $no_arg are (loosely) connected by their names. However, # there seems to be no specification about lexical variables # declared within a signature. if (!$no_arg) { say "$what: ", show $arg; $data = $arg; } else { say "$what: ", show $data; return $data; } } pass 'init'; no strict 'refs'; for my $sub (qw(no_sig sig_std sig_lexical)) { # Set to 1 and retrieve: &$sub("$sub setter", 1); is &$sub("$sub getter"), 1, "$sub get 1"; # Set to undef and retrieve: &$sub("$sub setter", undef); is &$sub("$sub getter"), U(), "$sub get undef"; SKIP: { skip "arg check without signature" if $sub =~ /^no/; # Too many arguments: like dies {&$sub("$sub invalid args", 42, 1)}, qr/Too many arguments/, "$sub with three args"; } } done_testing; __DATA__ # Seeded srand with seed '20201227' from local date. ok 1 - init no_sig setter: 1 no_sig getter: 1 ok 2 - no_sig get 1 no_sig setter: undef no_sig getter: undef ok 3 - no_sig get undef ok 4 - skipped test # skip arg check without signature sig_std setter: 1 sig_std getter: 1 ok 5 - sig_std get 1 sig_std setter: undef sig_std getter: undef ok 6 - sig_std get undef ok 7 - sig_std with three args sig_lexical setter: 1 sig_lexical getter: 1 ok 8 - sig_lexical get 1 sig_lexical setter: undef sig_lexical getter: undef ok 9 - sig_lexical get undef ok 10 - sig_lexical with three args 1..10