pragovnj:
I'm still a bit fuzzy on what you're asking. From your question title, it seems like you want to defer some calculations to a later time. While that's possible, the rest of your code implies that you're new to Perl.
So let's see if something simple will do what you want, first. Here's a bit of code that will keep a running sum of the input values. This lets you track the totals, but doesn't defer any calculations:
use strict;
use warnings;
# Place to accumulate the values
my %sum;
my $EquipName = "Switch";
my $slot = "1";
my $port = "FF";
while (my $INPUT_LINE = <DATA>) {
chomp $INPUT_LINE;
my $KEY = $EquipName . "." . $slot . "." . $port;
# Fetch out the values for the current line
my ($PvcCount, $LCir, $RCir) = split /\s+/, $INPUT_LINE;
# Add the values to the accumulators
$sum{PvcCount}{$KEY} += $PvcCount;
$sum{LCir}{$KEY} += $LCir;
$sum{RCir}{$KEY} += $RCir;
# Print the current values
print "Line $.: (PvcCount, LCir, RCir) "
. "CUR:($PvcCount, $LCir, $RCir) "
. "TTL:($sum{PvcCount}{$KEY}, $sum{LCir}{$KEY}, $sum{RCir}{$KE
+Y})\n";
}
__DATA__
1 2 3
2 4 9
3 8 27
4 16 81
This should give you the following results:
$ perl pm_11112793.pl
Line 1: (PvcCount, LCir, RCir) CUR:(1, 2, 3) TTL:(1, 2, 3)
Line 2: (PvcCount, LCir, RCir) CUR:(2, 4, 9) TTL:(3, 6, 12)
Line 3: (PvcCount, LCir, RCir) CUR:(3, 8, 27) TTL:(6, 14, 39)
Line 4: (PvcCount, LCir, RCir) CUR:(4, 16, 81) TTL:(10, 30, 120)
As you see, we created a hash called %sum to hold the totals as we read them in. So while processing a line, we have access to the total so far but aren't able to know the final total until the final line. If we wanted the output to be like this:
Line 1: (PvcCount, LCir, RCir) CUR:(1, 2, 3) TTL:(10, 30, 120)
Line 2: (PvcCount, LCir, RCir) CUR:(2, 4, 9) TTL:(10, 30, 120)
Line 3: (PvcCount, LCir, RCir) CUR:(3, 8, 27) TTL:(10, 30, 120)
Line 4: (PvcCount, LCir, RCir) CUR:(4, 16, 81) TTL:(10, 30, 120)
Then we'd have to read all the data before generating the output, because once we print a line, we can no longer change the values.
Some formats let you put things into the file in any order you like, such as PDF. If you were writing a PDF file, you could simply "remember" the locations to write the final values, and then when you hit the last line and can compute your totals, you could then write the totals in the remembered locations. For a Spreadsheet, you could provide a formula for computing the values and let the spreadsheet do the work when the spreadsheet user opens the sheet.
For a text file, though, you'd usually just parse the information and store it in a convenient format, and then after you're done reading the data, you'd then generate the report, something like this:
use strict;
use warnings;
# Place to accumulate the values
my %sum;
# Place to store data before we print it. When the KEY field changes,
+ we can then
# print all this data to the output
my @data;
my $previous_KEY="";
while (my $INPUT_LINE = <DATA>) {
chomp $INPUT_LINE;
# Fetch out the values for the current line
my ($EquipName, $slot, $port, $PvcCount, $LCir, $RCir)
= split /\s+/, $INPUT_LINE;
# Create the key to add the data to the proper thing
my $KEY = $EquipName . "." . $slot . "." . $port;
# If KEY doesn't match the old KEY, print the data then delete
# the data we no longer need.
if ($previous_KEY ne $KEY) {
print_data();
# then discard the (now unneeded) data and totals
@data = ();
%sum = ();
$previous_KEY = $KEY;
}
# Add the values to the accumulators
$sum{PvcCount} += $PvcCount;
$sum{LCir} += $LCir;
$sum{RCir} += $RCir;
# Store the data so we can print it later
push @data, [ $., $PvcCount, $LCir, $RCir ];
}
# Print data that may still be in @data and %sums
print_data();
# We made a subroutine to print the data because we need to
# call it from different places. Inside the loop, we need to
# print the data when the key changes. But we also need to
# call this it the end because there will probably still be
# some data in @data and %sum.
sub print_data {
my $KEY = shift;
for my $row (@data) {
print "Line $row->[0]: (PrvCount, LCir, RCir) "
. "CUR:($row->[1], $row->[2], $row->[3]) "
. "TTL:($sum{PvcCount}, $sum{LCir}, $sum{RCir})\n";
}
}
__DATA__
Switch 1 FF 1 2 3
Switch 1 FF 2 4 9
Switch 1 FF 3 8 27
Switch 1 FF 4 16 81
Router 5 DA 8 5 1
Router 5 DA 9 6 3
Router 5 DA 7 1 9
$ perl pm_11112793.pl
Line 1: (PrvCount, LCir, RCir) CUR:(1, 2, 3) TTL:(10, 30, 120)
Line 2: (PrvCount, LCir, RCir) CUR:(2, 4, 9) TTL:(10, 30, 120)
Line 3: (PrvCount, LCir, RCir) CUR:(3, 8, 27) TTL:(10, 30, 120)
Line 4: (PrvCount, LCir, RCir) CUR:(4, 16, 81) TTL:(10, 30, 120)
Line 5: (PrvCount, LCir, RCir) CUR:(8, 5, 1) TTL:(24, 12, 13)
Line 6: (PrvCount, LCir, RCir) CUR:(9, 6, 3) TTL:(24, 12, 13)
Line 7: (PrvCount, LCir, RCir) CUR:(7, 1, 9) TTL:(24, 12, 13)
As you can see, there's more work involved it you want to "go back in time" and print the final totals on
earlier lines. It's also not normally needed. Usually in reports we'll just print the totals *after* all
the details, which you can do with code more like the first example.
Hopefully this will help you with your project.
...roboticus
When your only tool is a hammer, all problems look like your thumb.
-
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.