Using __DATA__ in a program
Asked Answered
C

2

5

It is used on Stack Overflow all the time but I really don't understand it, nor can I get it to work. However it seems like a really good testing tool.

How do I get the script to read in everything below __DATA__ into a file handle? I tried a few ways to read it in instead of tacking on an external file. The data is legitimate, it is from the AutoSys JIL file for job definitions.

#!/efs/dist/perl5/core/5.10/exec/bin/perl

use strict;
use warnings;

my ( $job, $machine, $command, @line_stat );

#these 4 lines below do not read in data to filehandle
#my $data = do  {
#   local $/;
#   <DATA>;
#} ;

my $data = <DATA>;    # does not work either

open( my $fh, '<:encoding(UTF-8)', $data )
        or die "Could not open file '$data' $!";

my $count = 0;

while ( my $line = <$fh> ) {

    #chomp $line;
    if ( $line =~ /\/\* -{17} \w+ -{17} \*\// ) {
        $count = 1;
    }
    elsif ( $line =~ /(alarm_if_fail:)/ ) {
        $count = 0;
    }
    elsif ( $count ) {

        if ( $line =~ m/insert_job: (\w+).*job_type: CMD/ ) {
            push( @line_stat, $1 );
        }
        elsif ( $line =~ m/command:(.*)/ ) {
            push( @line_stat, $1 );
        }
        elsif ( $line =~ m/machine:(.*)/ ) {
            push( @line_stat, $1 );
        }
    }
}

foreach my $line_wot ( @line_stat ) {
    print "$line_wot\n";
}

__DATA__
/* ----------------- COME_AND_PLAY_WITH_US_DANNY ----------------- */

insert_job: COME_AND_PLAY_WITH_US_DANNY   job_type: CMD
command: /bin/bash -pwd
machine: capser.com
owner: twins
permission: foo,foo
date_conditions: 1
days_of_week: mo,tu,we,th,fr
start_times: "04:00"
description: "Forever, and ever and ever"
std_in_file: "/home/room217"
std_out_file: "${CASPERSYSLOG}/room217.out"
std_err_file: "${CASPERSYSLOG}/room217.err
alarm_if_fail: 1
profile: "/autosys_profile"
timezone: US/Eastern

/* ----------------- COME_AND_PLAY_WITH_US_AGAIN_DANNY ----------------- */

insert_job: COME_AND_PLAY_WITH_US_AGAIN_DANNY   job_type: CMD
command: /bin/bash -ls
machine: capser1.com
owner: twins
permission: foo,foo
date_conditions: 1
days_of_week: mo,tu,we,th,fr
start_times: "04:00"
description: "Forever, and ever and ever"
std_in_file: "/home/room217"
std_out_file: "${CASPERSYSLOG}/room217.out"
std_err_file: "${CASPERSYSLOG}/room217.err
alarm_if_fail: 1
profile: "/autosys_profile"
timezone: US/Eastern

/* ----------------- NEVER_PLAY_WITH_US_AGAIN_DANNY ----------------- */

insert_job: NEVER_PLAY_WITH_US_AGAIN_DANNY   job_type: CMD
command: /bin/bash -rm *
machine: capser2.com
owner: twins
permission: foo,foo
date_conditions: 1
days_of_week: mo,tu,we,th,fr
start_times: "04:00"
description: "Forever, and ever and ever"
std_in_file: "/home/room217"
std_out_file: "${CASPERSYSLOG}/room217.out"
std_err_file: "${CASPERSYSLOG}/room217.err
alarm_if_fail: 1
profile: "/autosys_profile"
timezone: US/Eastern
Catkin answered 23/10, 2017 at 19:40 Comment(4)
my $fh = \*DATA; instead of open my $fh...Yellowgreen
For clarity i prefer an explicit exit() just before DATA.Ernie
The DATA is a filehandle, much like STDIN; it reads data that follows the special __DATA__ literal. See __DATA__ (has link to perldata) and, for example, this post.Flashcube
BTW, DATA and END mean the same thing. Reading from DATA will read the lines after DATA or END, which ever one is first.Kahle
S
13

You don't need to open the DATA filehandle, just read from it.

while (my $line = <DATA>) {
    ...
}
Scrabble answered 23/10, 2017 at 19:45 Comment(1)
Yes, like STDIN, STDOUT, and STERR, DATA is automatically opened for you.Kahle
C
0

As documented in perldata:

Text after __DATA__ may be read via the filehandle PACKNAME::DATA , where PACKNAME is the package that was current when the __DATA__ token was encountered. The filehandle is left open pointing to the line after __DATA__

See SelfLoader for more description of __DATA__

Cleavable answered 11/1, 2018 at 9:38 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.