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

My script retrieves some data from a server into a variable. Here's a snippet that prints the data to STDOUT:
my $ua = init_lwp(); my $uri = create_query2($url, $newdate); my $resp_dat = execute_query($ua, $uri); print $resp_dat;
This works fine, but I want to insert a subroutine that I wrote separately into the script to parse the data and write to a file. The subroutine worked when I was testing it on its own with a sample data file. Now that I have the $resp_dat variable, I don't know how to send it to the subroutine. Or rather, I'm not sure how to receive it properly inside the subroutine. A modified version of the above snippet looks like this:
my $ua = init_lwp(); my $uri = create_query2($url, $newdate); my $resp_dat = execute_query($ua, $uri); subgen($resp_dat);
Here's the routine:
sub subgen { my($aref) = @_; my($cur_segno) = 0; my(@sst) = (); #open(FILE, my $aref); #or die "Cannot open: $file\n"; my $hdr = <>; #read in the first line chomp $hdr; my @colnames = split /, ?/, $hdr; #split the header into an array open GENFILE, '>genfile.txt'; open INFOFILE, '>infofile.txt'; my $sst_mean; my %fronts; while (<>) { chomp; next unless s/\"//g; # this will skip the first line and remov +e any " my(@colvalues) = split /, ?/; #read in the data @fronts{@colnames} = @colvalues; if ($fronts{segno2} == $cur_segno) { print GENFILE "$fronts{lon}, $fronts{lat}\n"; push(@sst, $fronts{sst}); } else { if ($cur_segno != 0) { print GENFILE "END\n"; print GENFILE "$fronts{segno2}\n", "$fronts{lon}, $fronts{lat}\n"; $sst_mean = calc_mean( \@sst ); print INFOFILE "$sst_mean\n", "$fronts{segno2}, "; } else { print GENFILE "$fronts{segno2}\n", "$fronts{lon}, $fronts{lat}\n"; print INFOFILE "$fronts{segno2}, "; } $cur_segno = $fronts{segno2}; @sst = (); } print GENFILE "END\n"; } close(FILE); close(GENFILE); close(INFOFILE); }
I've tried receiving it as @_ within the sub, but I think I'm invoking the <> incorrectly. Advice?

Replies are listed 'Best First'.
Re: Passing an array to a subroutine
by suaveant (Parson) on Jul 31, 2001 at 19:10 UTC
    You pretty much had it right before...
    #open(FILE, my $aref); #or die "Cannot open: $file\n";
    except your my $aref in the open is overriding the
    my ($aref} = @_;
    at the head of your subroutine, so aref in the open is undef... do
    open(FILE, $aref) or die "Cannot open: $file\n"; $line = <FILE>;
    and you should be golden

    <> works on @ARGV, not @_... if there is nothig it @ARGV it will read from STDIN

    Update oh yes, the while loop would also use <FILE> instead of <>

                    - Ant

      Thanks. I changed the code as you suggested, but my output files are empty. I ran this under the debugger with a break at that sub routine. When I type p @_ I get all the values in the array, but then p $aref is empty, and the rest of the routine, while it runs, is running on empty data. Thoughts?
      sub subgen { my $aref = @_; my($cur_segno) = 0; my(@sst) = (); open(FILE, $aref); #or die "Cannot open: $file\n"; my $hdr = <FILE>; #read in the first line chomp $hdr; my @colnames = split /, ?/, $hdr; #split the header into an array open GENFILE, '>genfile.txt'; open INFOFILE, '>infofile.txt'; my $sst_mean; my %fronts; while (<FILE>) { <snip>
        hmmm keep the () around your my $aref line...
        my ($aref) = @_; #or do my $aref = $_[0]; #or my $aref = shift;
        shift defaults to shift the first value off @_ if you don't supply an array argument.

                        - Ant

Re: Passing an array to a subroutine
by John M. Dlugosz (Monsignor) on Jul 31, 2001 at 19:23 UTC
    Here is a simple example:
    sub foo { my ($helper)= @_; $helper->(42, "Hello World"); } sub help1 { my ($value, $caption)= @_; print "$caption $value squared is",$value*$value,"\n"; } # main code foo (&help1);