yoda54 has asked for the wisdom of the Perl Monks concerning the following question:

Monks,

I keep getting "readline() on unopened filehandle DATA at (eval 1) line 5." when evaling a script with a __DATA__ section. Would you have any pointers to fix?

Thanks!

#!/usr/bin/perl use strict; use warnings; open(F, "test.pl"); my $f = do { local $/; <F> }; close(F); eval ($f); Test.pl: #!/usr/bin/perl use strict; use warnings; while (<DATA>) { chomp; print "TEST: *$_*\n"; } close DATA; __DATA__ TEST 1 2 3

Replies are listed 'Best First'.
Re: Losing __DATA__ when evaling script.
by Loops (Curate) on Jun 19, 2013 at 01:36 UTC

    If you add a __DATA__ section to the first script you'll see that it removes the error and allows the second script to be eval'd. Don't think there is a simple way to have an eval block extend the Data section.

    But for the example you've given above, everything in the first script can be replaced by:

    do 'test.pl';
    A reply falls below the community's threshold of quality. You may see it by logging in.
Re: Losing __DATA__ when evaling script.
by LanX (Saint) on Jun 19, 2013 at 01:36 UTC
    try do "test.pl" instead!

    see docs for "do EXPR" for details!

    Cheers Rolf

    ( addicted to the Perl Programming Language)

Re: Losing __DATA__ when evaling script.
by tobyink (Canon) on Jun 19, 2013 at 07:35 UTC

    The way that the DATA file handle works is intimately involved with how Perl loads files via do/require/use. What you are attempting will not work. Load your file using do/require/use; not eval.

    package Cow { use Moo; has name => (is => 'lazy', default => sub { 'Mooington' }) } say Cow->new->name
Re: Losing __DATA__ when evaling script.
by tobyink (Canon) on Jun 19, 2013 at 08:45 UTC

    For what it's worth, even though I don't think you should be doing this, the following works for your example:

    #!/usr/bin/perl use strict; use warnings; { no warnings "once"; open my $fh, "<", "test.pl"; my $code; while (<$fh>) { last if /^__DATA__/; $code .= $_; } local *DATA = $fh; eval $code; }

    However, it will break if test.pl contains a package statement taking it out of the same package as the wrapper script.

    package Cow { use Moo; has name => (is => 'lazy', default => sub { 'Mooington' }) } say Cow->new->name