Re: Why no warnings for 1 in void context?
by merlyn (Sage) on Jul 16, 2005 at 17:15 UTC
|
And just when you think you've got that figured out, check out these:
$ perl -wce '1; "ds"; "di"; "ig"; 0'
-e syntax OK
$
Then try other two-letter combos, which get the warnings. Why these? (I know!)
| [reply] [d/l] |
|
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...
| [reply] |
|
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.
| [reply] |
|
|
This thread makes me really glad Perl6 is throwing out all that old bathwater.
| [reply] |
|
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%?
| [reply] |
|
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. | [reply] [d/l] |
|
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.
| [reply] [d/l] [select] |
|
>echo 2 > Foo.pm
>perl -we "use Foo;"
>perl -cwe "use Foo;"
-e syntax OK
| [reply] [d/l] |
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 ....
?? | [reply] [d/l] [select] |
|
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;
| [reply] [d/l] [select] |
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.
| [reply] [d/l] [select] |
|
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
| [reply] |
|
It is actually always in scalar context. I learned this while trying to be a wise ass with Devel::FIXME.
| [reply] |
|
Yeah. I like to end modules with
42;
| [reply] [d/l] |
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.
| [reply] [d/l] |
Re: Why no warnings for 1 in void context?
by ikegami (Patriarch) on Jul 19, 2005 at 16:20 UTC
|
1 || <<'__COMMENT__';
...
__COMMENT__
but then again, I suppose you can do
=begin comment
...
=end comment
| [reply] [d/l] [select] |