$var = <LINE> ??

E

Eric Enright

Could someone please tell me why this code doesn't work?

----- begin "line.pl" -----
#!/usr/bin/perl

# output i'm expecting:
#
#-----begin-----
#foreach $outerline (<FIN>)
#{
# if ($outerline =~ /outerline/)
# {
# my $innerline;
#-----end-----
#
# ouput i get:
# <insert millions of empty lines here>
#
# i've tracked the problem down to the "$innerline = <FIN>;" line, however
# http://www.perldoc.com/perl5.8.0/pod/func/readline.html
# indicates this is valid??


use strict;

# assuming this source file is called "line.pl"
open(FIN, "<line.pl")
or die "unable to open myself for reading!??\n";

my $outerline;
foreach $outerline (<FIN>)
{
if ($outerline =~ /outerline/)
{
my $innerline;
while (!($innerline =~ /innerline/))
{
$innerline = <FIN>;
chomp($innerline);
print "$innerline\n";
}
}
}

close(FIN);
----- end "line.pl -----


Thank you kindly for any help in advance.
 
J

Joe Smith

Eric said:
Could someone please tell me why this code doesn't work?

foreach $outerline (<FIN>)

That says to read the entire file in all at once, then process it a line
at a time. There is nothing left for the inner loop to read.

You want to use a while(){} instead of a foreach(){}.
-Joe
 
A

Alf Timms

Could someone please tell me why this code doesn't work?

----- begin "line.pl" -----
#!/usr/bin/perl

# output i'm expecting:
#
#-----begin-----
#foreach $outerline (<FIN>)
#{
# if ($outerline =~ /outerline/)
# {
# my $innerline;
#-----end-----
#
# ouput i get:
# <insert millions of empty lines here>
#
# i've tracked the problem down to the "$innerline = <FIN>;" line, however
# http://www.perldoc.com/perl5.8.0/pod/func/readline.html
# indicates this is valid??


use strict;

# assuming this source file is called "line.pl"
open(FIN, "<line.pl")
or die "unable to open myself for reading!??\n";

my $outerline;
foreach $outerline (<FIN>)
{
if ($outerline =~ /outerline/)
{
my $innerline;
while (!($innerline =~ /innerline/))
{
$innerline = <FIN>;
chomp($innerline);
print "$innerline\n";
}
}
}

close(FIN);
----- end "line.pl -----


Thank you kindly for any help in advance.

Eric,

foreach $outerline (<FIN>)

this line is reading every line from FIN and storing them in a
temporary list before beginning the first iteration. so there is
nothing left in FIN to read with this line:

$innerline = <FIN>;

instead of the foreach loop use a while loop:

while( $outerline = <FIN> )

this would only read one line before each loop iteration.


alf
 
E

Eric Enright

Joe said:
That says to read the entire file in all at once, then process it a line
at a time. There is nothing left for the inner loop to read.

You want to use a while(){} instead of a foreach(){}.
-Joe

Ah, thanks Joe and Alf, I was under the impression that it would
only take one line per iteration. I got things working nicely
now.

Thanks!
 
T

Thomas Wasell

Eric Enright wrote on Wed, 07 Jul 2004 00:59:37 GMT in article
Could someone please tell me why this code doesn't work?

----- begin "line.pl" -----
#!/usr/bin/perl

# output i'm expecting:
#
#-----begin-----
#foreach $outerline (<FIN>)
#{
# if ($outerline =~ /outerline/)
# {
# my $innerline;
#-----end-----
#
# ouput i get:
# <insert millions of empty lines here>
#
# i've tracked the problem down to the "$innerline = <FIN>;" line,

That's not where the real problem lies, though!
however
# http://www.perldoc.com/perl5.8.0/pod/func/readline.html
# indicates this is valid??


use strict;

use warnings;

ALWAYS use warnings! They would have told you something
important:

Use of uninitialized value in:
(1) pattern match (m//) at line 33
(2) scalar chomp at line 36

repeated a zillion times. (Of course, if you add "use
warnings;", your line numbers will be different.)
# assuming this source file is called "line.pl"
open(FIN, "<line.pl")
or die "unable to open myself for reading!??\n";

Better:
or die "unable to open myself for reading: $!";

"$!" isn't comic-book-style cursing. It gives useful
information.

my $outerline;
foreach $outerline (<FIN>)

HERE is your real problem! foreach() will evaluate <FIN> in
list context, which means that the entire file will be read
into memory, and *then* $outerline will be assigned one line at
a time.
{
if ($outerline =~ /outerline/)
{
my $innerline;

Now $innerline = undef.
while (!($innerline =~ /innerline/))

[This is line 33.] First time around, $innerline = undef, and
undef doesn't match 'innerline', so this will loop. You will
also get warning (1).
{
$innerline = <FIN>;

We have already read past end-of-file said:
chomp($innerline);

[This is line 36.] Since $innerline = undef, this will give
you warning (2).
print "$innerline\n";
}

The while loop restarts, and since $innerline is still
undefined, it'll continue forever and ever...
}
}

close(FIN);
----- end "line.pl -----


Thank you kindly for any help in advance.

I'm sorry I couldn't provide any help in advance. :) Hope
this helps!

PS: This group ("comp.lang.perl") is defunct. You should use
"comp.lang.perl.misc" instead. Take a look at

perldoc -q usenet
 
E

Eric Enright

Thomas said:
Eric Enright wrote on Wed, 07 Jul 2004 00:59:37 GMT in article

use warnings;

ALWAYS use warnings! They would have told you something
important:

Use of uninitialized value in:
(1) pattern match (m//) at line 33
(2) scalar chomp at line 36

repeated a zillion times. (Of course, if you add "use
warnings;", your line numbers will be different.)

Duly noted.
HERE is your real problem! foreach() will evaluate <FIN> in
list context, which means that the entire file will be read
into memory, and *then* $outerline will be assigned one line at
a time.

I was under the impression that this was an efficient way to run
through a file line by line, without a lot of buffering. I read
this somewhere for a method of running through a million line
file without buffering it all first. Perhaps it was incorrect,
or more likely, I misinterpreted it/munged it in my memory.

I understand now though, and have things working well.
I'm sorry I couldn't provide any help in advance. :) Hope
this helps!
;-)

PS: This group ("comp.lang.perl") is defunct. You should use
"comp.lang.perl.misc" instead. Take a look at

perldoc -q usenet

Excellent! Thank you.
 
J

Joe Smith

Eric said:
I was under the impression that this was an efficient way to run
through a file line by line, without a lot of buffering. I read
this somewhere for a method of running through a million line
file without buffering it all first.

The way to go through a file line by line without a lot of buffering is
while(<FIN>) {...}
or
while(defined $outerline=<FIN>) {...}
and not use foreach().
-Joe
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,774
Messages
2,569,599
Members
45,175
Latest member
Vinay Kumar_ Nevatia
Top