Beefy Boxes and Bandwidth Generously Provided by pair Networks
laziness, impatience, and hubris
 
PerlMonks  

usage of '+' sign in say statement

by seki (Monk)
on Dec 05, 2017 at 16:19 UTC ( [id://1204972]=perlquestion: print w/replies, xml ) Need Help??

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

Hi Monks,

while looking for a setlocale + strftime example, I stumbled on this gist that makes a weird (for me) usage of the '+' sign with 'say':

use strict; use warnings; use utf8; use 5.10.0; use POSIX (); sub localize_strftime { my $locale = shift; my $default = POSIX::setlocale(POSIX::LC_TIME); POSIX::setlocale(POSIX::LC_TIME, $locale); my $retval = POSIX::strftime(@_); POSIX::setlocale(POSIX::LC_TIME, $default); return $retval; } say+localize_strftime('en_US', '%a, %d %b %Y %T %z', localtime(time));

Has it a specific meaning there, or is it just an habit with a precise goal in everyday code?

The best programs are the ones written when the programmer is supposed to be working on something else. - Melinda Varian

Replies are listed 'Best First'.
Re: usage of '+' sign in say statement
by kcott (Archbishop) on Dec 06, 2017 at 05:54 UTC

    G'day seki,

    Use of unary plus for disambiguation is common. Here's one instance in which I commonly use it:

    $ perl -wE 'say (1 == 0) ? "Yes" : "No"' say (...) interpreted as function at -e line 1. Useless use of a constant ("Yes") in void context at -e line 1. Useless use of a constant ("No") in void context at -e line 1. $ perl -wE 'say +(1 == 0) ? "Yes" : "No"' No

    There's nothing special about say:

    $ perl -wle 'print (1 == 0) ? "Yes" : "No"' print (...) interpreted as function at -e line 1. Useless use of a constant ("Yes") in void context at -e line 1. Useless use of a constant ("No") in void context at -e line 1. $ perl -wle 'print +(1 == 0) ? "Yes" : "No"' No $ perl -we 'printf (1 == 0) ? "Yes\n" : "No\n"' printf (...) interpreted as function at -e line 1. Useless use of a constant ("Yes\n") in void context at -e line 1. Useless use of a constant ("No\n") in void context at -e line 1. $ perl -we 'printf +(1 == 0) ? "Yes\n" : "No\n"' No

    There's also nothing special about the parenthesised list. Here, unary plus is used to disambiguate a hash key:

    $ perl -wle 'use constant X => "x"; my %x = (x => 42); print $x{X}' Use of uninitialized value in print at -e line 1. $ perl -wle 'use constant X => "x"; my %x = (x => 42); print $x{+X}' 42

    See the CAVEATS section of the constant pragma documentation for more on that.

    It's also used to disambiguate a right brace starting a block from one starting a hashref. The map documentation has multiple examples of this.

    "Has it a specific meaning there, or is it just an habit with a precise goal in everyday code?"

    The code in question works with and without the unary plus:

    $ perl -wE 'sub f { @_ } say f(42)' 42 $ perl -wE 'sub f { @_ } say+f(42)' 42 $ perl -wE 'sub f { @_ } say +f(42)' 42

    And Perl sees such code as being identical (see B::Deparse if you're unfamiliar with the following usage):

    $ perl -MO=Deparse,-p -e 'sub f { @_ } print f(42)' sub f { @_; } print(f(42)); -e syntax OK $ perl -MO=Deparse,-p -e 'sub f { @_ } print+f(42)' sub f { @_; } print(f(42)); -e syntax OK $ perl -MO=Deparse,-p -e 'sub f { @_ } print +f(42)' sub f { @_; } print(f(42)); -e syntax OK

    Of course, I can only guess at the original coders intentions:

    • Could be force of habit.
    • The author might be following some imposed coding standard.
    • Perhaps the unary plus was originally needed; then, when the code changed, it was just left in.
    • It might have been a typo which, causing no problems, raised no alarms during testing.
    • And, of course, it could be something entirely different.

    Finally, a friendly word of caution. You've received a number of replies: I strongly recommend that you take a quick look at "Worst Nodes" before deciding whose advice to take.

    — Ken

Re: usage of '+' sign in say statement
by Eily (Monsignor) on Dec 05, 2017 at 17:00 UTC

    Maybe this is to avoid the "Looks like a function" problem described in perlfunc. If you always call your functions followed by +, you probably won't fall into that trap, even when editing without care (note that under warnings perl will warn you if you make such a mistake). That's all that an unary + does anyway, it has no effect on its operand, and just changes the way perl interpretes a statement.

    Also note that this + is interpreted as unary because say accepts arguments, all functions that are declared to take none (empty prototype) will turn it into an addition:

    use v5.14; use warnings; use strict; sub my_say() { say $_[0] || "No arguments!"; } say (1+2)*3; # Same as (say(1+2))*3; say+(1+2)*3; # Same as say((1+2)*3); my_say+(1+2)*3; # Same as my_say()+(1+2)*3;
    say (...) interpreted as function at test.pl line 10. Useless use of multiplication (*) in void context at test.pl line 10. Useless use of addition (+) in void context at test.pl line 12. 3 9 No arguments!
Re: usage of '+' sign in say statement
by davies (Prior) on Dec 05, 2017 at 17:00 UTC
Re: usage of '+' sign in say statement
by herveus (Prior) on Dec 05, 2017 at 16:26 UTC
    Howdy!

    The "+" forces scalar context for the call to localize_strftime. I'm not clear on the benefit of that in this specific example, given that the sub is not context sensitive.

    yours,
    Michael

      Unary + doesn't do anything on its operand, unlike unary - which does force scalar context:

      use v5.14; use warnings; use strict; sub array { my @array = ("Hello ", "World"); @array; } say array; say+array; say-array; # warning here say scalar array;
      Ambiguous use of -array resolved as -&array() at context.pl line 13. Hello World Hello World -2 2

A reply falls below the community's threshold of quality. You may see it by logging in.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://1204972]
Approved by herveus
Front-paged by haukex
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others goofing around in the Monastery: (8)
As of 2024-04-19 15:08 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found