Question

In trying to answer an old question in a clever way, I was going to attempt this, not knowing if it would succeed:

#!/usr/bin/env perl

use strict;
use warnings;

use Tie::File;
tie( my @data, 'Tie::File', \*DATA ) or die "Cannot tie DATA";

foreach ( @data ) {
    print;
}

foreach ( @data ) {
    print scalar reverse;
}


__DATA__
one
two
three
four
five
six

I expected it to either work, or die; what I got was unexpected:

#!/usr/bin/env perluse strict;use warnings;use Tie::File;tie( my @data, 'Tie::File', \*DATA ) or die "Cannot tie DATA";foreach ( @data ) {    print;}foreach ( @data ) {    print scalar reverse;}__DATA__onetwothreefourfivesixlrep vne/nib/rsu/!#;tcirts esu;sgninraw esu;eliF::eiT esu;"ATAD eit tonnaC" eid ro ) ATAD*\ ,'eliF::eiT' ,atad@ ym (eit{ ) atad@ ( hcaerof;tnirp    }{ ) atad@ ( hcaerof;esrever ralacs tnirp    }__ATAD__enoowteerhtruofevifxis

How on earth did attempting to tie __DATA__ into Tie::File did it tie the script, and chomp it too?!

Was it helpful?

Solution

The DATA filehandle is just an open filehandle to the file that refers to it. It has some additional magic that the first time it is read from, it seeks to the first byte after the __DATA__ or __END__ token in your program, giving you the behavior you expect.

When you tie *DATA, you are getting in the way of the first-read magic, and getting a handle to your source file positioned at the top of the file.

I suspect that if you call tell DATA first (or maybe seek DATA,0,1) before you tie it, it will be in the correct position and "work" like you expected.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top