[perl] 続・初めてのPerl 第6章 「複雑なデータ構造の操作」

練習問題の回答をメモ。

ex06-1
#!/usr/bin/perl
use strict;
use warnings;
use Storable;

my $all = "**all machines**";
my $log_data_name = 'log_data';
my %total_bytes;

# 保存しておいた %total_bytes をロードする。ハッシュリファレンスをデリファレンスしてる。
if (-e $log_data_name) {
  my $data_ref = retrieve $log_data_name or die "Unable to retrieve from $log_data_name!\n";
  %total_bytes = %$data_ref;
}

while (<>) {
  next if /^#/;
  my ($source, $destination, $bytes) = split;
  $total_bytes{$source}{$destination} += $bytes;
  $total_bytes{$source}{$all} += $bytes;
}

# 過去のそれぞれのログデータの合計値をあらわす %total_bytes を保存して後で読めるようにしておく
store \%total_bytes, "$log_data_name" or die "Can’t store %total_bytes in $log_data_name!\n";

# ハッシュを値によってソートする 初めてのPerl p262
foreach my $source (sort { $total_bytes{$b}{$all} <=> $total_bytes{$a}{$all} } keys %total_bytes) {
  foreach my $destination (sort { $total_bytes{$source}{$b} <=> $total_bytes{$source}{$a} } keys %{ $total_bytes{$source} }) {
    next if $destination eq $all;
    print "$source => $destination: $total_bytes{$source}{$destination} bytes\n";
  }
  print "$source: $total_bytes{$source}{$all} total bytes sent\n";
  print "\n";
}

反省点

今回はやたら時間がかかった(1時間くらい)。
ログデータには「.log」などの拡張子を付けとくと後で保守しやすくなるかも。
store と retrieve の戻り値をチェックしよう。