pileofrogs has asked for the wisdom of the Perl Monks concerning the following question:

Hallo, ye monks so perlish.

This is just one of those things that I've never understood and never gotten around to asking. In most cases, the parenthesis following a function are optional, but in some cases, they seem to be downright forbidden. My most recent encounter was:

local($/ = chr 4);

Seems to set $/ globally. This flummoxed me to no end, until I tried:

local $/ = chr 4;

Which worked as expected.

There is another area where I've noticed that parenthesis seem to be forbidden, and I'd love to know why:

my @list = qw( why does this not work); map( { print $_."\n" }, @list );

These are points of confusion that I've lived with and never understood. Any light shed would be most appriciated.

Your humble obedient servant
--Pileofrogs

Replies are listed 'Best First'.
Re: Why is local($/) different from local $/?
by ikegami (Patriarch) on Mar 06, 2009 at 17:05 UTC

    local($/ = chr 4) works fine. "\x04" is assigned to $/, $/ is returned by the assignment, then $/ is localized.

    (local $/) = chr 4; would be the proper parenthesisation if you want the localisation to occur first.

    the parenthesis following a function are optional, but in some cases, they seem to be downright forbidden.

    local($/) = chr 4; would also be valid, but it has different semantics than local $/ = chr 4;

    local ($s) is considered a list when found on the LHS of an assignment, causing the list assignment (aassign) to be used. local $s is considered to be a scalar, so a scalar assignment (sassign) would be used then.

    $ perl -MO=Concise,-exec -e'local $s = "foo"' 2>&1 | grep assign 5 <2> sassign vKS/2 $ perl -MO=Concise,-exec -e'local ($s) = "foo"' 2>&1 | grep assign 7 <2> aassign[t2] vKS

    In practice:

    $ perl -le'my $x = local $s = "foo"; print $x' foo $ perl -le'my $x = local ($s) = "foo"; print $x' 1

    my, eof and use also vary in semantics based on the presence of parens.

    There is another area where I've noticed that parenthesis seem to be forbidden

    Red herring. It has nothing to do with parenthesis. map has two calling conventions, both of which work with and without parens:

    • map EXPR, LIST
    • map BLOCK LIST

    Your map has a block *and* a comma, which is wrong.

    map( { print $_."\n" } @list ); # Block and no comma works. map( print($_."\n"), @list ); # Expression with comma works. map { print $_."\n" } @list; # Block and no comma works. map print($_."\n"), @list; # Expression with comma works.

    By the way, why are you using map in void context?

    print "$_\n" for @list;

      Ah hah!! ++ Thank you! Now all is clear..

      I'm not actually using map in this way, I just remembered having this comma confusion and that was the simplest example I could conjure as a demonstration.