In Perl, why can't you use __DATA__ as a seekable filehandle?

In Perl, why can't you use __DATA__ as a seekable filehandle?



Reading from DATA via the typical slurp works. Trying to use DATA as a filehandle on which I can do a seek does not work. Is anyone able to point me the to the obvious mistake I must be making?



Code:


#!/usr/bin/env perl

use strict;
use warnings;

if ($ARGV[0] eq 'seek' )
my $log_fh = *DATA;
$log_fh->seek(64,0);
print "n-- 64 --n",join ("", <$log_fh> );
else
while (<DATA>)
print $_;



exit;

__DATA__
01234567890123456789
1234567890123456789
1234567890123456789
12
X <- That X is the 64th char in
this file.
Y <- That Y is the 106th char in this file.
junk
more junk.
bye!

$ perl file_from_data.pl slurp
01234567890123456789
1234567890123456789
1234567890123456789
12
X <- That X is the 64th char in
this file.
Y <- That Y is the 106th char in this file.
junk
more junk.
bye!



Running the while() loop:


$ perl file_from_data.pl slurp
01234567890123456789
1234567890123456789
1234567890123456789
12
X <- That X is the 64th char in
this file.
Y <- That Y is the 106th char in this file.
junk
more junk.
bye!



Running the seek(), it appears to not start at DATA but the start of the script:


$ perl file_from_data.pl seek

-- 64 --
'seek' )
my $log_fh = *DATA;
$log_fh->seek(64,0);
print "n-- 64 --n",join ("", <$log_fh> );
else
while (<DATA>)
print $_;



exit;

__DATA__
01234567890123456789
1234567890123456789
1234567890123456789
12
X <- That X is the 64th char in
this file.
Y <- That Y is the 106th char in this file.
junk
more junk.
bye!



This is an old Perl:


$ perl -v

This is perl 5, version 16, subversion 3 (v5.16.3) built for x86_64-linux-
thread-multi





DATA is seekable. Store the result of tell(DATA) when the script starts and treat that as the first byte of the DATA stream.
– mob
Aug 30 at 20:25


DATA


tell(DATA)


DATA





Avoid DATA if you need it seekable; use a separate file instead. Is this for a module you are distributing?
– ysth
Aug 30 at 20:43





For what it's worth, take a look at metacpan.org/pod/Data::Section::Simple. Not exactly what you describe you want to do, but maybe useful anyway.
– simbabque
Aug 31 at 8:50





@simbabque - I will keep this in my League of Extraordinary CPAN Modules. :-) Thank you.
– mpersico
Sep 1 at 13:36




1 Answer
1



Running the seek(), it appears to not start at DATA but the start of the script



I don't think you're making any mistake at all. That's exactly what happens. DATA is a filehandle that is open on your source file. Before your first read() from that filehandle, the file pointer is positioned immediately after the __DATA__ token in the file. But you can use seek() to move the file pointer to any position at all in the file.


DATA


read()


__DATA__


seek()



I guess it would be harder to implement a "special case" filehandle that wasn't able to move back before its initial position.





OP can just use SEEK_CUR (instead of SEEK_SET) as the whence.
– mwp
Aug 30 at 20:10





Duh - special semantics. So I should while() until DATA, get that position, then all seeks are relative to that. Sounds like something that is either on CPAN or should be. Thank you.
– mpersico
Aug 30 at 20:11





@mwp - Thanks! That worked: $log_fh->seek(64,1);
– mpersico
Aug 30 at 20:13






The other thing to do is: my $log_fh = *main::DATA; my $whence = $log_fh->tell(); $log_fh->seek($whence + 64,0); print "n-- 64 --n",join ("", <$log_fh> );
– mpersico
Aug 30 at 20:18



my $log_fh = *main::DATA; my $whence = $log_fh->tell(); $log_fh->seek($whence + 64,0); print "n-- 64 --n",join ("", <$log_fh> );





@mpersico, Don't search for __DATA__. You're already positioned there. Use SEEK_CUR to move forwards 64 bytes. If you need to seek back to the start, use tell to note the start position (before doing any seeking or reading)
– ikegami
Aug 30 at 20:53



__DATA__


SEEK_CUR


tell



Required, but never shown



Required, but never shown






By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Popular posts from this blog

𛂒𛀶,𛀽𛀑𛂀𛃧𛂓𛀙𛃆𛃑𛃷𛂟𛁡𛀢𛀟𛁤𛂽𛁕𛁪𛂟𛂯,𛁞𛂧𛀴𛁄𛁠𛁼𛂿𛀤 𛂘,𛁺𛂾𛃭𛃭𛃵𛀺,𛂣𛃍𛂖𛃶 𛀸𛃀𛂖𛁶𛁏𛁚 𛂢𛂞 𛁰𛂆𛀔,𛁸𛀽𛁓𛃋𛂇𛃧𛀧𛃣𛂐𛃇,𛂂𛃻𛃲𛁬𛃞𛀧𛃃𛀅 𛂭𛁠𛁡𛃇𛀷𛃓𛁥,𛁙𛁘𛁞𛃸𛁸𛃣𛁜,𛂛,𛃿,𛁯𛂘𛂌𛃛𛁱𛃌𛂈𛂇 𛁊𛃲,𛀕𛃴𛀜 𛀶𛂆𛀶𛃟𛂉𛀣,𛂐𛁞𛁾 𛁷𛂑𛁳𛂯𛀬𛃅,𛃶𛁼

Edmonton

Crossroads (UK TV series)