On Wed, Jan 19, 2022 at 7:00 PM Paul "LeoNerd" Evans <leonerd@leonerd.org.uk> wrote: > 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/ > I have one sad example to add: defining a sub that is passed as a callback to a module which doesn't document the (number of) arguments and call it in different parts with a different number of arguments. Example I'm just dealing with is Mojo::RabbitMQ::Client. In the end I gave up and didn't specify a signature to avoid exceptions caused by the different number of arguments. One more I can think of is different sub behavior depending on the number of arguments, like multi-dispatch but inside the sub. Then naming the arguments might be hard because for example the first one holds something different when paired with a second arg.Thread Previous | Thread Next