develooper Front page | perl.perl5.porters | Postings from December 2021

Re: "no snails"; or having signatured subs complain about @_

Thread Previous | Thread Next
From:
Dave Mitchell
Date:
December 9, 2021 15:01
Subject:
Re: "no snails"; or having signatured subs complain about @_
Message ID:
YbIaQQIpbU3Sp3id@iabyn.com
On Tue, Dec 07, 2021 at 06:02:23PM +0000, Paul "LeoNerd" Evans wrote:
> I think a lot of that isn't even necessary though. A variant of my
> no-snails branch which I haven't yet committed or pushed, very slightly
> relaxes the rules and allows a use of @_ as an rvalue in scalar
> context, purely to allow the code to determine the argument count.

I HATE that suggestion!

For one thing, @_ is still a real variable, containing the args of the
sub's (grand**N)parent, and will generally  be a different size than the
proposed value of scalar(@_).

E.g. (assuming for the sake of demonstration that @_ is accessible to
print at run time):

    sub sig ($a,$b) { print "@_"; print scalar @_ }
    sub plain       { sig(qw(d e)); }
    plain(qw(a b c));

outputs: (a b c 2), i.e. @_ contains 3 values but scalar(@_) returns 2.

Second, using the arg count as a way of determining whether a default arg
was passed etc, is awkward, ugly and error-prone for all but the simplest
subs:

    sub foo ($self, $base, $action, $flags, $result, $x, $y = 0, $z = 0) {
        my @point = ($x);
        push @point, $y if @_ > 6;
        push @point, $z if @_ > 7;
        $self->do_point(@point);
        ....
    }

whereas the query params proposal allows:


    sub foo ($self, $base, $action, $flags, $result,
            ?@point,
            $x, $y = 0, $z = 0)
        {
        $self->do_point(@point);
        ....
    }

(The example above is where you want to call point($x) rather than
point($x,0,0)  if the caller didn't supply y and z).

A perhaps more common example would be the equivalent for:

    sub foo {
        my $self = shift;
        my ($foo, $bar,...) = @_;
        do_something($foo, $bar,...);
        $self->SUPER::foo(@_) };
    }

which with query parameters becomes


    sub foo($self, ?@args, $foo, $bar,...) {
        do_something($foo, $bar,...);
        $self->SUPER::foo(@_) };
    }

PS - my intention is that the args will just be left on the stack,
@_ / padsv[0] will never be populated, and OP_ARG* get their values
directly from the stack.


-- 
Justice is when you get what you deserve.
Law is when you get what you pay for.

Thread Previous | Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About