seek and __DATA__ not behaving how I would hope

C

Chris Marshall

Hi

I am trying to use something like the script below (perl 5.6.0) to
iterate through the data at the bottom of the script several times (and
put an incremented parameter in there). However it does not seem
possible to seek back to the start of DATA. Can this be done in this
way or would I be better off using a here doc for the data and
iterating over the string many times ?

thanks,
Christian


cat ./test.pl
#!/usr/bin/perl
use warnings;
use strict;

for my $num (1..5){
while(<DATA>){
s/XX_NUM_XX/$num/;
print;
}
seek DATA, 0, 1;
print "seek $num\n"; #debug
}



__DATA__
hello XX_NUM_XX
world XX_NUM_XX


output:

../test.pl
hello 1
world 1
seek 1
seek 2
seek 3
seek 4
seek 5
 
A

Anno Siegel

Chris Marshall said:
Hi

I am trying to use something like the script below (perl 5.6.0) to
iterate through the data at the bottom of the script several times (and
put an incremented parameter in there). However it does not seem
possible to seek back to the start of DATA. Can this be done in this
way or would I be better off using a here doc for the data and
iterating over the string many times ?

The DATA filehandle is a read handle to your source file. When you
get to see it first, it "happens to be" positioned right past __END__
or __DATA__. When you seek to the beginning, it does just that and
positions to the first source line.

To reset the DATA handle to past __END__ you need to save the position
you find the filehandle in:
cat ./test.pl
#!/usr/bin/perl
use warnings;
use strict;
( my $data_pos = tell DATA) >= 0 or die "DATA not seekable";
for my $num (1..5){
while(<DATA>){
s/XX_NUM_XX/$num/;
print;
}
seek DATA, 0, 1;

You are positioning relative to the current position (second parameter
WHENCE is 1). An offset of 0 isn't going to change the position. You
meant "seek 0, 0", but really you want

seek DATA $data_pos, 0;
print "seek $num\n"; #debug
}

__DATA__
hello XX_NUM_XX
world XX_NUM_XX

Try these changes (untested), it may do what you want.

Anno
 
A

Anno Siegel

Chris Marshall said:
Hi

I am trying to use something like the script below (perl 5.6.0) to
iterate through the data at the bottom of the script several times (and
put an incremented parameter in there). However it does not seem
possible to seek back to the start of DATA. Can this be done in this
way or would I be better off using a here doc for the data and
iterating over the string many times ?

The DATA filehandle is a read handle to your source file. When you
get to see it first, it "happens to be" positioned right past __END__
or __DATA__. When you seek to the beginning, it does just that and
positions to the first source line.

To reset the DATA handle to past __END__ you need to save the position
you find the filehandle in:
cat ./test.pl
#!/usr/bin/perl
use warnings;
use strict;

( my $data_pos = tell DATA) >= 0 or die "DATA not seekable";
for my $num (1..5){
while(<DATA>){
s/XX_NUM_XX/$num/;
print;
}
seek DATA, 0, 1;

You are positioning relative to the current position (second parameter
WHENCE is 1). An offset of 0 isn't going to change the position. You
meant "seek 0, 0", but really you want

seek DATA, $data_pos, 0;
print "seek $num\n"; #debug
}

__DATA__
hello XX_NUM_XX
world XX_NUM_XX

Try these changes (untested), it may do what you want.

Anno
 
A

Anno Siegel

Chris Marshall said:
Works perfectly - thanks for the fix and the explanation.

Ugh. No attribution, no context. Oh right, X-Trace: posting.google.com.

Anno
 
C

Chris Marshall

Anno said:
Ugh. No attribution, no context. Oh right, X-Trace:
posting.google.com.

Sorry - you're completely right and I should have made that post much
better. First time I've posted in ages and (as I've since read -
everyone has found out) was caught out a little by the recent changes
in Google (But I should have checked the preview first).

Here is the completed example code with your corrections:

#!/usr/bin/perl
use warnings;
use strict;

for my $num (1..5){
( my $data_pos = tell DATA) >= 0 or die "DATA not seekable";
# correction from Anno: remember position of DATA
while(<DATA>){
s/XX_NUM_XX/$num/;
print;
}
seek DATA, $data_pos, 0; # correction from Anno: seek to
position of DATA
print "seek $num\n";
}

__DATA__
hello XX_NUM_XX
world XX_NUM_XX

Anno Siegel wrote:
Oh right, X-Trace: posting.google.com

True...an alternative to searching usenet than via google/groups is one
thing I've never looked into.
Could you offer me any advice here ? Both for at home (where I can
download or purchase any software but may or may not have news
available by my ISP) or from the office (where I am a lot more
restricted).

thanks
Christian
 
A

Anno Siegel

Chris Marshall said:
posting.google.com.

Sorry - you're completely right and I should have made that post much
better. First time I've posted in ages and (as I've since read -
everyone has found out) was caught out a little by the recent changes
in Google (But I should have checked the preview first).

Thanks for being so insightful.

[reading Usenet]
True...an alternative to searching usenet than via google/groups is one
thing I've never looked into.
Could you offer me any advice here ? Both for at home (where I can
download or purchase any software but may or may not have news
available by my ISP) or from the office (where I am a lot more
restricted).

Myself, I'm using trn, not because it's the best newsreader but because
it's the one I use. There are certainly more modern ones but trn is good
at what it does. It compiles on all (well, most) Unix systems. I'm sure
there are Win* ports too, Google will clear that up easily.

That's what Google is good at. The Usenet archive is nice, but they should
pack up their posting interface. It's doing Usenet a disservice.

What worries me most is that Google uses its immense prestige to turn
Usenet into Google Groups. Chances are that an arbitrary newcomer to
Usenet has come via Google, believing it's some kind of semi-static
web chat-room run by Google. We see examples of that daily. People
who know the difference may be a minority some not-too-far-away day.

Anno
 
D

David Combs

Myself, I'm using trn, not because it's the best newsreader but because
it's the one I use. There are certainly more modern ones but trn is good
at what it does. It compiles on all (well, most) Unix systems. I'm sure
there are Win* ports too, Google will clear that up easily.

NOT to start a *long* off-subject sub-thread, please let me know
what might be newer and/or better than trn (or trn4, which is
what I use -- probably you too?).

Please, short and sweet -- but maybe a sentence or two on what
you've heard about them.

Thanks,

David

PS: This is to NOT grow into anything more than this and maybe
two or three followups -- any more, and let's switch to that
newsgroups on newsreaders...

Thanks
 
T

Tad McClellan

David Combs said:
please let me know
what might be newer and/or better than trn


I switched from "trn" to "slrn" a few years ago because I wanted
its article-scoring features.

You can also survey User_Agent and/or X-Newsreader headers on posts
to see what other people are using.
 

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

No members online now.

Forum statistics

Threads
473,764
Messages
2,569,567
Members
45,041
Latest member
RomeoFarnh

Latest Threads

Top