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

The following code generates the warning Useless use of private variable in void context at noname.pl line 6. Line 6 being my $baz = $foo or $bar;:

use warnings; use strict; my $foo = 3; my $bar = 2; my $baz = $foo or $bar; print $baz;

The code prints 3 as expected despite the warning. Using || in place of or "fixes" the problem. Is this a (benign) bug, or something I don't understand about or?

This is using AS Perl 5.8.6


Perl is Huffman encoded by design.

Replies are listed 'Best First'.
Re: Bogus warning for low priority or, or something subtle
by Tanktalus (Canon) on Aug 05, 2005 at 03:40 UTC

    or has a lower precedence than =. Thus, your statement is parsed as (my $baz = $foo) or ($bar). Try changing $foo to 0 and see if you get what you think you should get.

      Something subtle then. I obviously don't read the Precedence chart often enough :)

      Thank you Tanktalus


      Perl is Huffman encoded by design.
Re: Bogus warning for low priority or, or something subtle
by blazar (Canon) on Aug 05, 2005 at 08:29 UTC
    As a general rule, that AFAICT has not been mentioned so far, the low precedence logical operators are better suited for flow control and the high precedence ones for most other things, e.g. for operating on values.
Re: Bogus warning for low priority or, or something subtle
by EvanCarroll (Chaplain) on Aug 05, 2005 at 06:17 UTC
    Juxtapose this:
    perl -e'print q/foo/ and q/bar/;' perl -e'print q/foo/ && q/bar/;

    Also see this:
    perl -e'print UNDEF q/foo/ or die; perl -e'print UNDEF q/foo/ || die;


    Evan Carroll
    www.EvanCarroll.com
Re: Bogus warning for low priority or, or something subtle
by basha (Initiate) on Aug 05, 2005 at 10:42 UTC
    Try to do like this $baz=($foo or $baz); And then prints. It wont gives warning. $baz=$foo or $bar; "=" operator has higher precedence.so it default take $ foo value.
Re: Bogus warning for low priority or, or something subtle
by tlm (Prior) on Aug 05, 2005 at 22:25 UTC

    For this sort of question I like using B::Deparse,-p:

    % perl -MO=Deparse,-p 481076.pl Useless use of private variable in void context at 481076.pl line 10. use warnings; use strict 'refs'; (my $foo = 3); (my $bar = 2); ((my $baz = $foo) or $bar); print($baz); 481076.pl syntax OK
    There you have it, plain as day.

    Unfortunately, B::Deparse is not always accurate. Therefore, if necessary, I corroborate with B::Concise, whose output I find much harder to read than B::Deparse's, but is more accurate.

    the lowliest monk

      I seem to recall seeing mention of a way of getting more verbose error and warning messages, but can't remember how. That will earn someone a ++ :)


      Perl is Huffman encoded by design.
Re: Bogus warning for low priority or, or something subtle
by pg (Canon) on Aug 05, 2005 at 05:11 UTC

    This is definitely interesting. I personally never noticed that or actually has a different precedency as ||. I don't like it, and don't think that gives anyone any real benefit.

    What was the thinking behind this? My guess is that, they want to give you the feeling that, || is used to connect "fragments" within a "statment", and or is used to conect "statements", sort of treating Perl like a natural language. In this sense, or comes after ||.

      It's so you can:

      my $importantValue = SomethingTricky () or die "A nasty thing happend\ +n";

      Perl is Huffman encoded by design.
      This is definitely interesting. I personally never noticed that or actually has a different precedency as ||. I don't like it, and don't think that gives anyone any real benefit.
      The different precedence is the whole point of having two "or" and two "and" operators in the first place. Read perlop under "Logical Or and Exclusive Or".

      The or (and and) was introduced with perl 5.000 as described in the Changes5.0000 :

      New "and" and "or" operators work just like && and || but with a precedence lower than comma, so they work better with list operators.
      The reason that they are separate operator is to ensure "least surprise" and not to break existing code by changing the precedence of the existing operators. I guess it was also considered that it would be more expressive to have the two sets of operators with different precedence.

      I'm sure if you were to send a patch reversing this to p5p it would be given the consideration it deserves.

      /J\

      I personally never noticed that or actually has a different precedency as ||. I don't like it, and don't think that gives anyone any real benefit.

      Nice attitude. The first time you encounter some feature, you not only dismiss it for yourself, but you dismiss it for everyone. Stop and think about something for its benefits before you write such a blanket statement about "anyone."

      --
      [ e d @ h a l l e y . c c ]