tags:

views:

214

answers:

3

I have some simple Perl code:

#!/usr/bin/perl

use strict;   # not in the OP, recommended
use warnings; # not in the OP, recommended

my $val = 1;
for ( 1 .. 100 ) {
    $val = ($val * $val + 1) % 8051;
    print ($val / 8050) . " \n";
}

But when I run it, the output is:

bash-3.2$ perl ./rand.pl
0.0002484472049689440.000621118012422360.003229813664596270.08409937888198760.92
... <snipped for brevity> ...
2919250.9284472049689440.3526708074534160.1081987577639750.2295652173913040.1839
751552795030.433540372670807bash-3.2$

Am I doing something wrong?

A: 

It is possible that the line is interpreted as follows

(print($val / 8050)) . " \n";

i.e. the parentheses being used as delimiters for a function argument list, with the ."\n" being silently discarded. Try:

 print( ($val/8050) . "\n" );
Paul Dixon
That didn't work, though I didn't vote you down.Also, the word you want is "its", not "it's."
rlbond
-1 for greengrocers apostrophes? Far too slow with my edit though, Sinan was fast!
Paul Dixon
@rlbond: I don't think what you said about "its" and "it's" is right. Though not a native english speaker, I think that "its" is the possesive form of "it", while "it's" is the abbreviation of "it is". So I think that Paul Dixons use of "It's" is perfectly correct.
Inshallah
No, they were right, I had wrote "Each OS has it's quirks" :)
Paul Dixon
@Inshalla: He edited the reply. it's = it is, its = that which belongs to it.
rlbond
Ah, that clears it up. Was just looking it up in the dictionary :)
Inshallah
You only need to worry about `\r\n` if you set `binmode()` on the file handle.
Brad Gilbert
I downvoted because of the \r\n red herring. In Perl -- with binmode off -- this isn't ever the issue (echoing Sinan Ünür above). Edit that out, and this is a correct response and a good line of reasoning.
clintp
@Paul I removed the bit about `"\r\n"` because there is no need to keep wrong information up and there is no need for that to cost you downvotes.
Sinan Ünür
+17  A: 

C:\> perldoc -f print:

Also be careful not to follow the print keyword with a left parenthesis unless you want the corresponding right parenthesis to terminate the arguments to the print--interpose a + or put parentheses around all the arguments.

Therefore, what you need is:

print( ($val / 8050) . "\n" );

or

print +($val / 8050) . "\n";

The statement you have prints the result of $val / 8050 and then concatenates "\n" to the return value of print and then discards the resulting value.

Incidentally, if you:

use warnings;

then perl will tell you:

   print (...) interpreted as function at t.pl line 5.
   Useless use of concatenation (.) or string in void context at t.pl line 5.
Sinan Ünür
Wow, I feel stupid. Makes sense though.
rlbond
Nice catch! +1
RC
@rlbond Don't worry about it. Everyone gets bitten by this once in a while. On the other hand, +1 for a well written question with a succinct example.
Sinan Ünür
@rlbond: No reason to feel stupid, it's definitely not a pretty aspect of perl. Baroque.
Axeman
@Brad thank you for the edit but I rolled back because `<kbd>` does indicate the important fact that the documentation can be accessed on the user's computer.
Sinan Ünür
+1 for suggesting to use warnings. Regarding the use of `<kbd>`, I think that this is intended to signify a single keypress, and what you want to convey should just be in `<pre>` tags, perhaps with a prompt character before.
Svante
@Svante: No. See http://www.w3.org/TR/html401/struct/text.html **KBD:** Indicates text to be entered by the user.
Sinan Ünür
+3  A: 

This is more of a comment than an answer, but I don't know how else to make it and the question is already answered anyway.

Note that using say instead of print neatly sidesteps the whole issue. That is,

#!/usr/bin/perl

use 5.010;
use strict;
use warnings;

my $val = 1;
for ( 1 .. 100 ) {
    $val = ($val * $val + 1) % 8051;
    say ($val / 8050);
}

works as intended without the issue even coming up. I'm still amazed at how useful say is, given it's such a tiny difference.

oylenshpeegul
+1. Good point. Not everyone has upgraded yet, though.
Sinan Ünür