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

Dear Monks,

I now have a code that runs but doesn't print what I want

#!/usr/bin/perl; use strict; use warnings; my $fin = "SELECTDAT2"; my $fout = "myfile"; open my $ih, '<', $fin or die "cannot open $fin for reading, $! "; open my $oh, '>', $fout or die "cannot open $fout for writing, $! "; while (<$ih>) { my @tokens = split; my $SEC1 = $tokens[4], my $LAT = $tokens[5], my $LONG = $tokens[6], my + $DEPTH = $tokens[7], my $NO = $tokens[11], my $GAP = $tokens[12]; my $nextline = <$ih>; $nextline; my $y = $tokens[0], my $m = $tokens[1], my $d = $tokens[2], my $h = $t +okens[3]; sub events { my @list; foreach $nextline (@list) { if ($nextline le $NO) { my @tokens = split; my $SOURCE = $tokens[0], my $PSEC = $tokens[4], my $PQ = $tokens[5], m +y $SSEC = $tokens[8], my $SQ = $tokens[9]; push (@list, $_); } } return @list; } last line if $nextline eq ""; print $oh "$NO\n", "events($@list)\n", "$SEC1, $LONG, $LAT, $DEPTH, $G +AP\n"; } close ($oh); close ($ih);

this is one event from my file SELECTDAT2

82 2 22 1043 54.7 48.020 114.037 17.5 3.2 2.9 13 177 84.3 0.20 +1.6 2.7 C MBMG * 3.1 KALISPELL VALLEY; FELT 3.07 82022210 BUT EP 4432.804ES60.7 LRM IPD4435.40 IS67.2 180. AMM IPD4429.50 ES57.3 133. MSO EPC4415.90 ES32.3 CMT EP 4430.50 IS58.3 LDM IPC4412.20 ES24.3 3 RXF EPC4414.3 CLX IPC4408.70 ES19.7

this is what my code prints out in myfile.

177 events(list) 54.7, 114.037, 48.020, 17.5, 84.3 events(list) , , , , events(list) , , , , events(list) , , , ,

this is what I want printed out

13 'BUT' 4432.80 4 60.7 0 'LRM' 4435.40 0 67.2 0 'AMM' 4429.50 0 57.3 0 'MSO' 4415.90 0 32.3 0 'CMT' 4430.50 0 58.3 0 'LDM' 4412.20 0 24.3 3 'RXF' 4414.3 0 'CLX' 4408.70 0 19.7 0 54.7 114.037 48.020 17.5 177 GO ON TO NEXT EVENT DATA SET

I can't figure why my 'myfile' is not printing out as I want it to with my code.

Replies are listed 'Best First'.
Re: redrafted code
by wind (Priest) on Feb 02, 2011 at 06:18 UTC
    Well, one problem is your function call is embedded in a string where it won't be called. Take this
    print $oh "$NO\n", "events($@list)\n", "$SEC1, $LONG, $LAT, $DEPTH, $G +AP\n";
    to
    print $oh "$NO\n", events($@list), "\n$SEC1, $LONG, $LAT, $DEPTH, $GAP +\n";
    Also, in case anyone else wants to help further, here's the code with better spacing.
    #!/usr/bin/perl; use strict; use warnings; my $fin = "SELECTDAT2"; my $fout = "myfile"; open my $ih, '<', $fin or die "cannot open $fin for reading, $! "; open my $oh, '>', $fout or die "cannot open $fout for writing, $! "; while (<$ih>) { my @tokens = split; my $SEC1 = $tokens[4]; my $LAT = $tokens[5]; my $LONG = $tokens[6]; my $DEPTH = $tokens[7]; my $NO = $tokens[11]; my $GAP = $tokens[12]; my $nextline = <$ih>; $nextline; my $y = $tokens[0]; my $m = $tokens[1]; my $d = $tokens[2]; my $h = $tokens[3]; sub events { my @list; foreach $nextline (@list) { if ($nextline le $NO) { my @tokens = split; my $SOURCE = $tokens[0]; my $PSEC = $tokens[4]; my $PQ = $tokens[5]; my $SSEC = $tokens[8]; my $SQ = $tokens[9]; push (@list, $_); } } return @list; } last line if $nextline eq ""; print $oh "$NO\n", events($@list), "\n$SEC1, $LONG, $LAT, $DEPTH, +$GAP\n"; } close ($oh); close ($ih);

    - Miller

      Thanks!! I was having trouble figuring out how to call subroutines in perl.

Re: redrafted code
by lyklev (Pilgrim) on Feb 02, 2011 at 08:21 UTC

    Move the subroutine definition to somewhere else, for example to the top of your code, before the main part of the code starts. Then call the subroutine at the point in the code where you have now defined it.

    Also note that when you split a line:

    • the first token starts at index 0, so your latitude will be $tokens[4] and your longitute will be $tokens[5];
    • the last token will contain the newline at the end of the line, so before splitting, you might want to chomp the line.
      Move the subroutine definition to somewhere else, for example to the top of your code, before the main part of the code starts.

      Perl 5 parses the entire code before running it, so this is only relevant if your sub declaration relies on runtime effects.