Beefy Boxes and Bandwidth Generously Provided by pair Networks
Your skill will accomplish
what the force of many cannot
 
PerlMonks  

Why no warnings for 1 in void context?

by tlm (Prior)
on Jul 16, 2005 at 16:03 UTC ( [id://475466]=perlquestion: print w/replies, xml ) Need Help??

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

Update: As Not_a_Number points out below, the behavior described in this post applies not only to 1 (as I originally stated), but to 0 as well. And, after reading merlyn's post, well, it looks like there's a huge number of constants—all those strings beginning with "di", "ds", or "ig"—that perl won't warn about when they are evaluated in a void context. See the code responsible for this behavior, kindly posted by AM.


OK, here's another idle Perl arcana question. A scalar constant in a void context will result in a warning, unless this constant evaluates to a numeric value of 1; e.g.:

% perl -wce 5 Useless use of a constant in void context at -e line 1. -e syntax OK % perl -wce 1 -e syntax OK % perl -wce '5**0' -e syntax OK % perl -wce 1.00 -e syntax OK % perl -wce 'q(1)' Useless use of a constant in void context at -e line 1. -e syntax OK
Does anyone know the rationale for this special dispensation for (numeric) 1? The only one I can think of (and it's a pretty tortured one) is that it silences the warning that would have otherwise been triggered by the usual require-appeasing "1;" when one checks a module's syntax using perl -wc.

the lowliest monk

Replies are listed 'Best First'.
Re: Why no warnings for 1 in void context?
by merlyn (Sage) on Jul 16, 2005 at 17:15 UTC

      Well, also "ignoramus" and "dimwit" (which, BTW, pretty much describe my state right now) sail through without warnings... After some googling, I suspect the special treatment of such strings has something to do with nroff/troff/groff, but I know zilch about these, so I'll have to leave it at that...

      the lowliest monk

        Very good! Yes, it's a little known feature of perl that certain nroff directives are legal in perl, in the sense that they are always recognized, even if not defined. (They will not override or change the meaning of any actual definitions in your code.) The place to begin is in op.c, in function Perl_scalarvoid. Here we learn that any symbol occurring in void context which begins with 'di', 'ds', or 'ig' is given a pass to sail by without warning.

        (In the exact same place, 0 and 1 are defined as non-warning-worthy in void context. merlyn knew that, of course.)

        The code tells us to look in the pink camel [that's Programming Perl 1st ed.], near page 319. This is where two scripts, wrapman and wrapinst, are presented. This is really the best clue to why these nroff directives are special... and what it boils down to is Larry's (clever) attempt to make it easy to document code by making it possible for (some) code to be both legal perl and legal nroff. I think even he would admit that it wasn't terribly successful. But this was in the days before POD.

        No doubt this feature has been exploited in obfu.

      This thread makes me really glad Perl6 is throwing out all that old bathwater.

        Yeah, I've often wondered how much faster Perl 5 would be if it didn't have to support a whole bunch of deprecated and/or obsolete features from previous versions of Perl. (Granted, the support for the feature discussed in this post probably has a minuscule impact on perl's performance, but there may be others that are not so negligible.) 1%? 10%?

        the lowliest monk

Re: Why no warnings for 1 in void context?
by dave_the_m (Monsignor) on Jul 16, 2005 at 16:06 UTC
    It's so that code like the following works without warnings:
    1 while ....
    NB - the 1 in a require isn't evaluated in a void context, so it wouldn't generate a warning anyway.

    Dave.

      1 while ....

      That makes sense. Thanks.

      NB - the 1 in a require isn't evaluated in a void context...

      It is if, as I wrote, you syntax-check I did not write about the normal situation in which a module is require-ed; I referred to the case when one syntax-checks the module's file with perl -wc, e.g.:

      % echo 1 > Foo.pm % perl -wc Foo.pm Foo.pm syntax OK % echo 2 > Foo.pm % perl -wc Foo.pm Useless use of a constant in void context at Foo.pm line 1. Foo.pm syntax OK
      (Hey, I did say it was a tortured rationale!)

      But yes, normally, when a module is require'd the 1 (or whatever) is not evaluated in a void context.

      Update: I fixed the wording, in response to ikegami's reply. The question of whether doing a syntax check on a module with perl -wc somehow turns it into a script is too metaphysical even for me.

      the lowliest monk

        It is if, as I wrote, you syntax-check the module's file with perl -wc, e.g.:

        Then it's no longer a module, it's just a script. The parent poster did say "in a require".

        >echo 2 > Foo.pm >perl -we "use Foo;" >perl -cwe "use Foo;" -e syntax OK
Re: Why no warnings for 1 in void context?
by Not_a_Number (Prior) on Jul 16, 2005 at 17:03 UTC
    A scalar constant in a void context will result in a warning, unless this constant evaluates to a numeric value of 1...

    Actually, the same is true of zero:

    % perl -wce 0 -e syntax OK

    Given dave_the_m's explanation above, is this to allow:

    0 until ....

    ??

      Actually, the same is true of zero:

      % perl -wce 0 -e syntax OK

      Yes, thank you, and also of undef and (), and of any list whose elements are the scalars already identified; e.g.:

      % perl -wce '( 1, 0, undef, , "di foo", "ds bar", "ig baz" )' -e syntax OK

      Given dave_the_m's explanation above, is this to allow:

      0 until ....
      ??

      Reading between the lines, I gather that you are attaching some significance to the boolean value of the constant in question. I did too on a first reading, but then I realized that it is the boolean value of what follows the while or until that matters. I.e.,

      1 while some_condition_with_side_effects;
      has the same effect as
      0 while some_condition_with_side_effects;

      the lowliest monk

Re: Why no warnings for 1 in void context?
by davido (Cardinal) on Jul 16, 2005 at 16:25 UTC

    It is so that the convention of ending a module with 1; won't trigger a warning. Modules must return truth, and it's common practice to put a 1; on the last line to satisfy this criteria.

    See perlmod for supporting documentation.


    Dave

      The final line of a required module isn't in void context - it's the return value of the require. Try putting something else there and you'll see there's no warning. I worked with a guy who put (unfortunately copyrighted) poetry in a string at the end of his modules.

      -sam

        It is actually always in scalar context. I learned this while trying to be a wise ass with Devel::FIXME.

        -nuffin
        zz zZ Z Z #!perl
        Yeah. I like to end modules with 42;
Re: Why no warnings for 1 in void context?
by GrandFather (Saint) on Jul 16, 2005 at 18:21 UTC

    also used as "body" in module files:

    1;
    Update: Argh, read the original post!

    Perl is Huffman encoded by design.
Re: Why no warnings for 1 in void context?
by ikegami (Patriarch) on Jul 19, 2005 at 16:20 UTC

    It also makes it easy to comment out sections:

    1 || <<'__COMMENT__'; ... __COMMENT__

    but then again, I suppose you can do

    =begin comment ... =end comment

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others scrutinizing the Monastery: (4)
As of 2024-04-19 02:53 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found