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
Borodin
  • 126,100
  • 9
  • 70
  • 144
capser
  • 2,442
  • 5
  • 42
  • 74
  • `my $fh = \*DATA;` instead of `open my $fh...` – mpapec Oct 23 '17 at 19:48
  • 1
    For clarity i prefer an explicit exit() just before __DATA__. – ulix Oct 23 '17 at 19:57
  • The `DATA` _is_ a filehandle, much like `STDIN`; it reads data that follows the special `__DATA__` literal. See [\_\_DATA\_\_](http://perldoc.perl.org/functions/__DATA__.html) (has link to `perldata`) and, for example, [this post](https://stackoverflow.com/questions/13463509/the-data-syntax-in-perl). – zdim Oct 23 '17 at 20:23
  • BTW, __DATA__ and __END__ mean the same thing. Reading from DATA will read the lines after __DATA__ or __END__, which ever one is first. – shawnhcorey Oct 24 '17 at 12:07

2 Answers2

13

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

while (my $line = <DATA>) {
    ...
}
Jim Davis
  • 5,241
  • 1
  • 26
  • 22
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__

Eugen Konkov
  • 22,193
  • 17
  • 108
  • 158