Front page | perl.perl5.porters |
Postings from May 2012
[perl #96006] Some unary functions accept multiple arguments
Thread Next
From:
Father Chrysostomos via RT
Date:
May 12, 2012 12:10
Subject:
[perl #96006] Some unary functions accept multiple arguments
Message ID:
rt-3.6.HEAD-4610-1336849835-691.96006-14-0@perl.org
On Sun Jul 31 13:54:42 2011, sprout wrote:
> perl56delta has this section:
>
> Better syntax checks on parenthesized unary operators
> Expressions such as:
>
> print defined(&foo,&bar,&baz);
> print uc("foo","bar","baz");
> undef($foo,&bar);
>
> used to be accidentally allowed in earlier versions, and
> produced
> unpredictable behaviour. Some produced ancillary warnings when
> used in
> this way; others silently did the wrong thing.
>
> The parenthesized forms of most unary operators that expect a
> single
> argument now ensure that they are not called with more than one
> argument, making the cases shown above syntax errors. The
> usual
> behaviour of:
>
> print defined &foo, &bar, &baz;
> print uc "foo", "bar", "baz";
> undef $foo, &bar;
>
> remains unchanged. See perlop.
>
>
> A few of unary functions survived, though:
>
> prototype(1,2,3) evaluates 1 and 2 in void context, using 3 (in scalar
> context) as its argument. That’s harmless, although a bit
> surprising. eval() behaves the same way.
I’ve been thinking about this on and off for some time.
!($foo, $bar) evaluates $foo in void context and $bar in scalar context.
If we were to change that to ‘too many arguments for !’, we would have
a lynch mob after us.
The same applies to not($foo, $bar) and scalar($foo, $bar).
So I’ve been wondering why chr and getprotobynumber (for example) need
to refuse more than one argument. How are these fundamentally different
from not and scalar?
If I get a void warning when writing scalar(3, foo()), isn’t that
sufficient for other ops as well?
Now, there is one case where it makes sense to refuse more than one
argument: scalar lvalue context.
I’m using the term lvalue in the broad sense of anything that goes
through op_lvalue internally, which means anything with a prototype
containing \$, \[$@%&*] or \[$@%*], or that parses as though it had such
a prototype.
In the case of untie(%foo,%bar), it is completely counterintuitive that
%bar should be untied, but not %foo. So in this case it makes sense to
refuse more than one argument (which doesn’t currently happen).
What I propose we do is make built-in functions with a prototype (or
effective prototype) of ($), (;$), (*), (;*) or (_) allow more than one
argument, but treat it as a single scalar expression (i.e., with a
scalar comma); and make built-in functions with a(n effective) prototype
of (\$), (\[$@%*]), etc. refuse more than one argument.
Now, should the laxity regarding ($) apply to user-defined subroutines, too?
--
Father Chrysostomos
Thread Next
-
[perl #96006] Some unary functions accept multiple arguments
by Father Chrysostomos via RT