Re: Internally, how do for() and while() differ?
by BrowserUk (Patriarch) on Oct 27, 2015 at 00:04 UTC
|
Do they really?
No.
- The former places the readline in a list context, slurps the whole file and then processes that list in the loop, one line at a time.
- The latter places the readline in a scalar context, reads one line at a time and then prints it before looping back to read the next line.
With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
In the absence of evidence, opinion is indistinguishable from prejudice.
| [reply] |
|
| [reply] |
Re: Internally, how do for() and while() differ?
by AppleFritter (Vicar) on Oct 27, 2015 at 00:04 UTC
|
No; the for loop will slurp all of $fh into memory and then iterate over that, whereas while will only read one line at a time. | [reply] |
Re: Internally, how do for() and while() differ?
by shmem (Chancellor) on Oct 27, 2015 at 07:41 UTC
|
As others already said, no. Here's what the compiler backend B (B::Terse) says, running
perl -MO=Terse -le 'for(<>){print}'
perl -MO=Terse -le 'while(<>){print}'
substituting the addresses with 0x? and running 'vimdiff for while':
==================== for ====================|=================== while ===================
LISTOP (0x?) leave [1] | LISTOP (0x?) leave [1]
OP (0x?) enter | OP (0x?) enter
COP (0x?) nextstate | COP (0x?) nextstate
BINOP (0x?) leaveloop | BINOP (0x?) leaveloop
LOOP (0x?) enteriter | LOOP (0x?) enterloop
OP (0x?) null [3] | ---------------------------------------------
UNOP (0x?) null [147] | ---------------------------------------------
OP (0x?) pushmark | ---------------------------------------------
UNOP (0x?) readline [2] | ---------------------------------------------
PADOP (0x?) gv GV (0x?) *ARGV | ---------------------------------------------
PADOP (0x?) gv GV (0x?) *_ | ---------------------------------------------
UNOP (0x?) null | UNOP (0x?) null
LOGOP (0x?) and | LOGOP (0x?) and
OP (0x?) iter | UNOP (0x?) defined
---------------------------------------------| UNOP (0x?) null
---------------------------------------------| UNOP (0x?) null [15]
---------------------------------------------| PADOP (0x?) gvsv GV (0x?) *_
---------------------------------------------| UNOP (0x?) readline [2]
---------------------------------------------| PADOP (0x?) gv GV (0x?) *ARGV
LISTOP (0x?) lineseq | LISTOP (0x?) lineseq
COP (0x?) nextstate | COP (0x?) nextstate
LISTOP (0x?) print | LISTOP (0x?) print
OP (0x?) pushmark | OP (0x?) pushmark
UNOP (0x?) null [15] | UNOP (0x?) null [15]
PADOP (0x?) gvsv GV (0x?) *_ | PADOP (0x?) gvsv GV (0x?) *_
OP (0x?) unstack | OP (0x?) unstack
which shows,that for gobbles up all lines (LOOP enteriter) to process each (OP iter) after that, whereas the while loop (LOOP enterloop) processes readline and print in the loop body (LOOP enterloop).
perl -le'print map{pack c,($-++?1:13)+ord}split//,ESEL'
| [reply] [d/l] [select] |
Re: Internally, how do for() and while() differ?
by LanX (Saint) on Oct 27, 2015 at 00:59 UTC
|
for iterates over a list, everything in brackets is expanded (the only exception are ranges ). So <> will create a temporary list.
while loops as long a boolean expression is true.
This can be used together with an iterator, like while($x=iter()) .
There is no general automatism to set $_ like your example implies, that's just magic behavior of the file iterator <> in scalar context. that boolean context.
| [reply] [d/l] [select] |
|
$ perl -MO=Deparse,-p -le "while(<>){print}"
BEGIN { $/ = "\n"; $\ = "\n"; }
while (defined(($_ = <ARGV>))) {
print($_);
}
-e syntax OK
$ perl -MO=Deparse,-p -le "while($f=<>){print}"
BEGIN { $/ = "\n"; $\ = "\n"; }
while (defined(($f = <ARGV>))) {
print($_);
}
-e syntax OK
$ echo hi |perl -le "while($f=<>){print}"
You see <> in scalar context didn't set $_ | [reply] [d/l] [select] |
|
I meant while's scalar context, and only this iterator.
Should be documented ( perlsyn ? )
UPDATE
see perlop#IO-Operators :
> If and only if the input symbol is the only thing inside the conditional of a while statement (even if disguised as a for(;;) loop), the value is automatically assigned to the global variable $_ , destroying whatever was there previously.
| [reply] |
Re: Internally, how do for() and while() differ?
by Anonymous Monk on Oct 27, 2015 at 00:38 UTC
|
Try it with a really, really big file. :)
| [reply] |
Re: Internally, how do for() and while() differ?
by MidLifeXis (Monsignor) on Oct 27, 2015 at 13:36 UTC
|
I think you also want to be careful about the truthiness of your input values with while. See defined for an approach.
Update: Hmm, after testing, I am not sure on this advice. Possibly ignore me.
Update 2: confirmed - while (<>) {...} ... is Perl shorthand for the more explicitly written ... while (defined($line = <ARGV>)) {...}
| [reply] [d/l] [select] |
Re: Internally, how do for() and while() differ?
by ikegami (Patriarch) on Oct 27, 2015 at 16:07 UTC
|
They are not even close to being equivalent, as evidenced by
my @a = qw( a b c );
for (@a) {
print("$_\n"); # Prints "a", then "b", then "c".
}
while (@a) {
print("$_\n"); # Prints an infinite number of blank lines.
}
| [reply] [d/l] |
|
The two examples are equivalent in operation, since they have the <> operator around a file handle. In the case of arrays, which the OP did not specify, you are correct. Unless, again, the <> operator is used.
@a = qw(a b c);
for(<@a>) { print "$_\n" };
while(<@a>) { print "$_\n" };
Both produce the same output, the while loop with considerably more efficiency for large datasets.
| [reply] [d/l] |
|
> Unless, again, the <> operator is used.
Sorry for nitpicking, but IMHO it's not the same "operator" here.
The OP uses a readline and you are applying a glob.*
That's one of the more confusing magic features of Perl, so I'm open for further discussion on this matter.
*)
similarly are range and flipflop different, even when written with ..
| [reply] [d/l] |
|
Re: Internally, how do for() and while() differ?
by jeffa (Bishop) on Oct 27, 2015 at 17:48 UTC
|
For further reading, i recommend doing a little studying on how loops are implemented in assembly language:
You don't have to be an assembly language expert, but simply browsing over the details can be enough to help you better understand the underlying "differences." ;)
jeffa
L-LL-L--L-LL-L--L-LL-L--
-R--R-RR-R--R-RR-R--R-RR
B--B--B--B--B--B--B--B--
H---H---H---H---H---H---
(the triplet paradiddle with high-hat)
| [reply] |
A reply falls below the community's threshold of quality. You may see it by logging in. |