develooper Front page | perl.perl5.porters | Postings from July 2011

[perl #96006] Some unary functions accept multiple arguments

From:
Father Chrysostomos
Date:
July 31, 2011 13:54
Subject:
[perl #96006] Some unary functions accept multiple arguments
Message ID:
rt-3.6.HEAD-7815-1312145682-1204.96006-75-0@perl.org
# New Ticket Created by  Father Chrysostomos 
# Please include the string:  [perl #96006]
# in the subject line of all future correspondence about this issue. 
# <URL: https://rt.perl.org:443/rt3/Ticket/Display.html?id=96006 >


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.

When called in list context readline and readpipe evaluate their arguments in list context, and then pop the topmost item leaving everything else there, in addition to the value intended to be returned.

In scalar context readline and readpipe act like prototype.

In dynamic context (determined at run-time; e.g., at the end of a sub) readline and readpipe propagate their context to *all* their arguments. So readpipe(foo(),foo()) at the end of a subroutine makes both foo calls in scalar context if the subroutine is called in scalar context, but calls the first foo in void context if readpipe can be determined at compile time to be in scalar context.

Here are some examples:

$ perl -le'open my $foo, "<", \"bar";  print readline("baz",$foo)'
bazbar

$ perl -le'open my $foo, "<", \"bar";  print "baz",$foo,readline(sub{}->())'
bazbar

Context of readline’s operands:

$ perl -le 'sub context { print qw[void scalar list][wantarray + defined wantarray] } readline(context,context)'
void
void

which means that a function called in void context can return a value (the second readline would give bar, not baz, if get_foo’s retval were ignored):

$ perl -le 'open my $foo, "<", \"bar\nbaz"; sub get_foo {print qw[void scalar list][wantarray + defined wantarray]; $foo } readline(get_foo); print scalar readline $foo'
void
baz

$ perl -le 'sub context { print qw[void scalar list][wantarray + defined wantarray] } $x = readline(context,context)'
void
scalar

$ perl -le 'sub context { print qw[void scalar list][wantarray + defined wantarray] } () = readline(context,context)'
list
list

Context of readline’s operands in dynamic context:

$ perl -le 'sub context { print qw[void scalar list][wantarray + defined wantarray] } sub { readline(context,context) }->()'
void
void

$ perl -le 'sub context { print qw[void scalar list][wantarray + defined wantarray] } $x = sub { readline(context,context) }->()'
scalar
scalar

$ perl -le 'sub context { print qw[void scalar list][wantarray + defined wantarray] } () = sub { readline(context,context) }->()'
list
list

---
Flags:
    category=core
    severity=low
---
Site configuration information for perl 5.15.0:

Configured by sprout at Thu Jun 16 05:42:17 PDT 2011.

Summary of my perl5 (revision 5 version 15 subversion 0) configuration:
  Snapshot of: 00b4043708e2509400eff8f5e4cb870d388854d4
  Platform:
    osname=darwin, osvers=10.5.0, archname=darwin-thread-multi-2level
    uname='darwin pint.local 10.5.0 darwin kernel version 10.5.0: fri nov 5 23:20:39 pdt 2010; root:xnu-1504.9.17~1release_i386 i386 '
    config_args='-de -Dusedevel -Duseithreads'
    hint=recommended, useposix=true, d_sigaction=define
    useithreads=define, usemultiplicity=define
    useperlio=define, d_sfio=undef, uselargefiles=define, usesocks=undef
    use64bitint=undef, use64bitall=undef, uselongdouble=undef
    usemymalloc=n, bincompat5005=undef
  Compiler:
    cc='cc', ccflags ='-fno-common -DPERL_DARWIN -fno-strict-aliasing -pipe -fstack-protector -I/usr/local/include',
    optimize='-O3',
    cppflags='-fno-common -DPERL_DARWIN -fno-strict-aliasing -pipe -fstack-protector -I/usr/local/include'
    ccversion='', gccversion='4.2.1 (Apple Inc. build 5664)', gccosandvers=''
    intsize=4, longsize=4, ptrsize=4, doublesize=8, byteorder=1234
    d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=16
    ivtype='long', ivsize=4, nvtype='double', nvsize=8, Off_t='off_t', lseeksize=8
    alignbytes=8, prototype=define
  Linker and Libraries:
    ld='env MACOSX_DEPLOYMENT_TARGET=10.3 cc', ldflags =' -fstack-protector -L/usr/local/lib'
    libpth=/usr/local/lib /usr/lib
    libs=-ldbm -ldl -lm -lutil -lc
    perllibs=-ldl -lm -lutil -lc
    libc=/usr/lib/libc.dylib, so=dylib, useshrplib=false, libperl=libperl.a
    gnulibc_version=''
  Dynamic Linking:
    dlsrc=dl_dlopen.xs, dlext=bundle, d_dlsymun=undef, ccdlflags=' '
    cccdlflags=' ', lddlflags=' -bundle -undefined dynamic_lookup -L/usr/local/lib -fstack-protector'

Locally applied patches:
    

---
@INC for perl 5.15.0:
    /usr/local/lib/perl5/site_perl/5.15.0/darwin-thread-multi-2level
    /usr/local/lib/perl5/site_perl/5.15.0
    /usr/local/lib/perl5/5.15.0/darwin-thread-multi-2level
    /usr/local/lib/perl5/5.15.0
    /usr/local/lib/perl5/site_perl
    .

---
Environment for perl 5.15.0:
    DYLD_LIBRARY_PATH (unset)
    HOME=/Users/sprout
    LANG=en_US.UTF-8
    LANGUAGE (unset)
    LD_LIBRARY_PATH (unset)
    LOGDIR (unset)
    PATH=/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/usr/X11/bin:/usr/local/bin
    PERL_BADLANG (unset)
    SHELL=/bin/bash




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