* Bret Hughes [Mon, Feb 19, 2001 at 12:39:22AM -0600]:
> i believe you. I just can't figure out what it is doing? I have been
> working with perl lately and always looking to learn. Can you explain
> what it is doing please?
>
> this also appears to work:
> perl -e 'rand($.)<1&&($l=$_)while<>;print $l;' < file
>
> The $. is the current line from the last read filehandle,in the case
> stdin, right? Does < file pass the file to the program or just the file
> name?
It redirects the standard input so that the script gets input from
a file instead of the keyboard.
> That seems to imply we have read all the way through the file at least
> once I think.
The algorithm makes one complete pass over the file before it makes up
its mind, yes.
>
> rand() will return a random number between 0 and the argument so will
> this ever play the last file in the list if $. is the last line number?
>
> I get lost pretty quick. the <1&&($l=$_)while<> contruct totally
> baffles me other than knowing that while <> will read lines in from
> stdin, $1=$_ will set variable $1 to the text of the current line but
> beyond that I have no idea how it is all working together.
>
> One of the issues I have with perl and experiencd perl programmers is
> the tendency to create really compact and I guess efficient code such as
> this one liner that are difficult to figure out for the less advanced of
> us out here.
It's a form of abstraction; once you know what it does you don't have
to figure out how it does it every time you use it, just copy it into
your script. And I want it to fit on one line!
>
> Anyway, help me learn to fish instead of just giving me a fish sandwich,
> please. That way I can become enlightened and start writing code that
> only I can debug :)
>
There was a typo in my original mail. Here's the correct version of
the command:
perl -e 'srand;rand($.)<1&&($l=$_)while<>;print $l;' < file
The 'srand' function seeds the random number generator. It's not
strictly necessary in newer versions of perl (there's an implicit
call to 'srand' at the first use of 'rand').
Here's the same script in a less compact but easier-to-understand
form:
01 #!/usr/bin/perl
02
03 srand;
04 while (<>)
05 {
06 if (rand($.) < 1)
07 {
08 $line = $_;
09 }
10 }
11 print $line;
As you can see, I've rewritten the '(EXPR1) while (EXPR2)' statement
into a more readable 'while (EXPR) BLOCK' (line 4), and the
'(EXPR1) && (EXPR2)' statement into an 'if (EXPR) BLOCK'. Otherwise
it's pretty much the same.
For each loop iteration, a new input line is read and stored into
the $_ variable (this is what <> does). Line 6 is where the magic
occurs: $. holds the current line number (starting from 1, call it N),
so the call to rand will always produce a random fractional number in
the range 0..N. As you can see, the probability of selecting a line is
always 1/lines_read and thus the final probability for each line becomes
1/N.
The selected line is then printed on line 11.
--
Johannes Eriksson <[EMAIL PROTECTED]>
Computer Science, AA University
_______________________________________________
Redhat-list mailing list
[EMAIL PROTECTED]
https://listman.redhat.com/mailman/listinfo/redhat-list