Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

perl

seek

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
like image 225
mpersico Avatar asked Aug 30 '18 20:08

mpersico


1 Answers

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.

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

like image 102
Dave Cross Avatar answered Oct 12 '22 23:10

Dave Cross