On 2022-01-23 12:16 p.m., Juerd Waalboer wrote: > Paul "LeoNerd" Evans skribis 2022-01-19 17:59 (+0000): >> * 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 signatured($x = undef) { >> # impossible to distinguish signatured() from signatured(undef) >> } > > A simple workaround is possible by introducing a new undef-like value that has > this very specific purpose: > > use Scalar::Util qw(refaddr); > use constant NONE => \do { my $x }; > sub _provided($x) { ref($x) && refaddr($x) == refaddr(NONE) } > > sub bar($self, $new = NONE) { > $self->{bar} = $new if _provided($new); > $self->{bar}; > } > > As checking arity for combined getter/setter methods is incredibly common, maybe > it would make sense to have a very tiny module, maybe even core, that exports > these, or to add them to Scalar::Util. > > Of course, this depends on not using the constant for other purposes. I think > that's mostly a matter of documenting that the behavior of any other use of the > constant is undefined. I still oppose as wrong-headed the concept of using such sentinel default values to try and detect when no argument is passed. The only use of such default values is when you don't care to distinguish between users explicitly passing that value from them not passing anything. When you actually want to distinguish them not passing a value, DON'T use defaults, and instead use "@" to capture the list and test the list for presence of an element. -- Darren DuncanThread Previous | Thread Next