Holidayish Greetings, Monks --
Today I had to whip up a quick script, which typically makes me nervous, and I noticed something that to my still-baby-Perl eyes seemed ... well, interesting, I guess.
I had to create some reports from a couple of tab-delimited text files, so as I usually do, I opened filehandles to them:
open (my $INFILE_1, '<', 'name_o_file.txt') ||
croak "Cannot open input file: $!\n";
... and same deal for a second file / handle.
I then created subroutines to create the reports, and tried passing the filehandles into the subroutines. It worked fine for the first subroutine, but when I passed the same filehandles to a SECOND subroutine ... nothing happened. No output. It was as though I had not called that second subroutine at all.
I only explicitly closed the filehandles after the second subroutine call.
Just because I got desperate, I tried creating TWO MORE filehandles to the same files, and passing those to the second subroutine. This worked.
What is happening here? Do filehandles get auto-closed when they are passed to a subroutine and the subroutine returns?
(this is probably really basic, but somehow I have never encountered it before).
UPDATE: of course, I should _think_ before I post (and post code as well)
Here is what doesn't work:
open(my $CDA1, '<', 'cda1_raw.txt') ||
croak "Cannot open input file 1: $!\n";
open(my $CDA2, '<', 'cda2_raw.txt') ||
croak "Cannot open input file 2: $!\n";
report_one($CDA1, 'cda1_boffle.txt');
report_one($CDA2, 'cda2_boffle.txt');
report_two($CDA1, $CDA2, $dbh);
close $CDA1;
close $CDA2;
And here is what worked:
open(my $CDA1, '<', 'cda1_raw.txt') ||
croak "Cannot open input file 1: $!\n";
open(my $CDA2, '<', 'cda2_raw.txt') ||
croak "Cannot open input file 2: $!\n";
report_one($CDA1, 'cda1_boffle.txt');
report_one($CDA2, 'cda2_boffle.txt');
open(my $CDA3, '<', 'cda1_raw.txt') ||
croak "Cannot open input file: $!\n";
open(my $CDA4, '<', 'cda2_raw.txt') ||
croak "Cannot open input file: $!\n";
report_three ($CDA3, $CDA4, $dbh);
close $CDA1;
close $CDA2;
close $CDA3;
close $CDA4;
And here is the report_one sub:
sub report_one {
my ($input_handle, $output_name) = @_;
open(my $OUT, '>', "$output_name") ||
croak "Cannot open output file: $!\n";
my $current_host = "";
my %host_counts;
my @rows = (<$input_handle>);
foreach ( @rows ) {
my ($date, $time, $host, $bytes, $bytes_sec, $server)
+= split /\t/;
if ( ( $bytes < 1000000 ) || ( $bytes == $bytes_sec )
+) {
next;
}
if ( $host eq $current_host ) {
$host_counts{$host}{bytes} += $bytes;
$host_counts{$host}{speed} += $bytes_sec;
$host_counts{$host}{count}++;
} else {
$host_counts{$host}{bytes} = $bytes;
$host_counts{$host}{speed} = $bytes_sec;
$host_counts{$host}{count} = 1;
}
$current_host = $host;
}
foreach my $heauxst ( keys %host_counts ){
my $avg_speed = int( $host_counts{$heauxst}{speed} / $
+host_counts{$heauxst}{count} );
print $OUT "$heauxst\t$host_counts{$heauxst}{bytes}\t$
+avg_speed\n";
}
close $OUT;
return;
}
-
Are you posting in the right place? Check out Where do I post X? to know for sure.
-
Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
<code> <a> <b> <big>
<blockquote> <br /> <dd>
<dl> <dt> <em> <font>
<h1> <h2> <h3> <h4>
<h5> <h6> <hr /> <i>
<li> <nbsp> <ol> <p>
<small> <strike> <strong>
<sub> <sup> <table>
<td> <th> <tr> <tt>
<u> <ul>
-
Snippets of code should be wrapped in
<code> tags not
<pre> tags. In fact, <pre>
tags should generally be avoided. If they must
be used, extreme care should be
taken to ensure that their contents do not
have long lines (<70 chars), in order to prevent
horizontal scrolling (and possible janitor
intervention).
-
Want more info? How to link
or How to display code and escape characters
are good places to start.