I'm currently having a bit of hack at the docs in perlsub.pod,
adjusting the wording about @_ when talking about signatured
subroutines (ahead of merging my branch[1] to add discouragement
warnings to it). I feel it would be useful to keep in mind a concrete
list of the things that signatured subs don't let us do right now, so
we can think about future ideas:
* Setting @_ so you can do a 'goto &SUB' tailcall (or a perl4-style
call but we don't like those any more); much as you would with
sub not_signatured {
@_ = ("args", "to", "callee");
goto &elsewhere;
}
sub signatured($x) {
@_ = ... # not allowed
}
* Seeing the entire collection of arguments so you can write a simple
wrapper-function and forward on everything to a callee:
sub not_signatured {
my ($x) = @_;
warn "Calling with x=$x\n";
return otherfunc(@_);
}
sub signatured($x, @) {
warn "Calling with x=$x\n";
return otherfunc(@_); # not allowed
}
* As a variant of the above; you can't even see the count of passed
arguments in order to distinguish no-argument from being explicitly
passed undef (or whatever the param default is)
sub not_signatured {
my ($x) = @_;
warn "X was " ? (@_ ? "the value $x" : "not passed");
}
sub signatured($x = undef) {
# impossible to distinguish signatured() from signatured(undef)
}
* Assigning to or otherwise mutating the caller's arguments:
sub not_signatured {
$_[0] = uc $_[0];
}
sub signatured($x) {
$_[0] = uc $x; # not allowed
}
If we make signatures non-experimental and add the warning about @_
being forbidden, we should keep these cases in mind. At the very least
I'd like to document them, but ideally we should further investigate,
for each of them, whether we're actually happy to tell users "yeah,
don't do that" or whether we feel we need to provide some alternative
facility to allow them to continue writing functions to perform that
kind of behaviour, while using signatures.
[1] - https://github.com/Perl/perl5/pull/19346
--
Paul "LeoNerd" Evans
leonerd@leonerd.org.uk | https://metacpan.org/author/PEVANS
http://www.leonerd.org.uk/ | https://www.tindie.com/stores/leonerd/
adjusting the wording about @_ when talking about signatured
subroutines (ahead of merging my branch[1] to add discouragement
warnings to it). I feel it would be useful to keep in mind a concrete
list of the things that signatured subs don't let us do right now, so
we can think about future ideas:
* Setting @_ so you can do a 'goto &SUB' tailcall (or a perl4-style
call but we don't like those any more); much as you would with
sub not_signatured {
@_ = ("args", "to", "callee");
goto &elsewhere;
}
sub signatured($x) {
@_ = ... # not allowed
}
* Seeing the entire collection of arguments so you can write a simple
wrapper-function and forward on everything to a callee:
sub not_signatured {
my ($x) = @_;
warn "Calling with x=$x\n";
return otherfunc(@_);
}
sub signatured($x, @) {
warn "Calling with x=$x\n";
return otherfunc(@_); # not allowed
}
* As a variant of the above; you can't even see the count of passed
arguments in order to distinguish no-argument from being explicitly
passed undef (or whatever the param default is)
sub not_signatured {
my ($x) = @_;
warn "X was " ? (@_ ? "the value $x" : "not passed");
}
sub signatured($x = undef) {
# impossible to distinguish signatured() from signatured(undef)
}
* Assigning to or otherwise mutating the caller's arguments:
sub not_signatured {
$_[0] = uc $_[0];
}
sub signatured($x) {
$_[0] = uc $x; # not allowed
}
If we make signatures non-experimental and add the warning about @_
being forbidden, we should keep these cases in mind. At the very least
I'd like to document them, but ideally we should further investigate,
for each of them, whether we're actually happy to tell users "yeah,
don't do that" or whether we feel we need to provide some alternative
facility to allow them to continue writing functions to perform that
kind of behaviour, while using signatures.
[1] - https://github.com/Perl/perl5/pull/19346
--
Paul "LeoNerd" Evans
leonerd@leonerd.org.uk | https://metacpan.org/author/PEVANS
http://www.leonerd.org.uk/ | https://www.tindie.com/stores/leonerd/