sironekotoroの日記

Perl で楽をしたい

すぐわかる オブジェクト指向 Perl 第3章 配列のリファレンス

わかる

  • いきなり引用

ここで、2つの配列 @tanka と @kosuu を渡すと、売り上げ金額の合計を返すサブルーチン &uriage を考えてみます。
サブルーチンの中身を書く前に、メインのプログラムでこのサブルーチンを呼び出す方法を考えてみます。
&uriage(@tanka,@kosuu)
でしょうか。いや、ここでこれがいきなりダメです。
というのは、サブルーチンの引数は、サブルーチンの内部で
@_
という配列に入るのですが

  • ガッテンガッテン!
  • なるほど、そうか、そりゃそうだ
  • サブルーチンの引数に配列そのまま突っ込むとダメ、展開されちゃうってのは知ってたけど、 @_ に入れるからか、そうか、改めて説明されるとそうか、そりゃそうだ

2つ以上の配列をサブルーチンに渡す

やる気とお時間があればここでいったんしおりを挟んで本を閉じ、ご自分で書いてみてください

  • 学習本において、こう書かれていたら、やってみなくては実力が付かない
  • 自分が最初に書いたもの
sub uriage {
    my ($ref_tanka , $ref_kosuu) = @_;
    my @tanka = @$ref_tanka;
    my @kosuu = @$ref_kosuu;
    my $sum;
    foreach my $soeji (0 .. $#tanka){
        $sum += $tanka[$soeji] * $kosuu[$soeji];
    }
    return $sum
};
  • 途中の
    foreach my $soeji (0 .. $#tanka){

    foreach my $soeji ($#tanka){
    って書いて事故った。
  • 同じ要素数の配列なので、配列のインデックス順に2つの配列にアクセスしていけば良いという考え
  • 本に載ってたのはこちら
sub uriage {
    my ( $ref_tanka, $ref_kosuu ) = @_;
    my $uriage = 0;
    foreach my $tanka (@$ref_tanka) {
        my $kosuu = shift @$ref_kosuu;
        $uriage += $tanka * $kosuu;
    }
    return $uriage;
}
  • shift をそう使うのか!なるほど
  • for ブロックの中で配列(のリファレンス)を操作するのか
  • デリファレンスした配列をそのまま foreach に入れるのか

  • いろんなやり方見るの楽しい。

    • 短いプログラムですぐに理解できるようなものなら、なお楽しい

濃いなぁ

  • 先の2章があっさりだったが本章は濃い
my @month = qw/january february march april may june july august september november deccember/;

$refMonth = \@month;

print "refMonth: $refMonth -> @$refMonth" , "\n" , "No.5 : $$refMonth[4]";
  • スカラーデリファレンス・・・?

    • 配列の要素はスカラーだから間違いではないか

    $refMonth のリファレントを配列としてでリファレンスしたものに、 [4] をインデックス付けしたもの

  • Perlエンジンの名前の解釈の仕方

    • 名前を見つけたら、その前を見る: $$refMonth[4] の 'refMonth' が名前、その直前だと $ ($$の内側、後ろの方)
    • 記号 $ を解決する。すなわち $refMonthスカラー
    • さらに、前に記号 $ がまだあるので、それを解決。 $$refMonthスカラーへのリファレンス
      • 先の2章で「役に立たない」と言われていたスカラーのリファレンスじゃないすか
    • 前には記号がもうないので、名前の後ろを解釈していく
    • [4] は配列の5番目の要素(0はじまりだから)、つまりリファレント(参照先)は配列と判断
    • 後ろにはもう何もない。解釈終了。
  • Perl の気持ち

$$refMonth[4]${$refMonth[4]} の違い

  • $$refMonth[4] はリファレンス化した配列の4番目のインデックスの要素
  • ${$refMonth[4]} は・・・
    • {} コードブロックで分けてあるので、そこまでの処理で一度とまる
    • スカラー $refMonth
    • コードブロックあるから、後ろを見る
    • 配列の5番目を示すスカラー $refMonth[4]
      • @refmonth の 5番目?
    • $refMonth[4] の要素をデリファレンスしたもの?つまり、リファレンスが入っている?
my $rm1  = 'january';
my $rm2  = 'february';
my $rm3  = 'march';
my $rm4  = 'april';
my $rm5  = 'may';
my $rm6  = 'june';
my $rm7  = 'july';
my $rm8  = 'august';
my $rm9  = 'september';
my $rm10 = 'october';
my $rm11 = 'november';
my $rm12 = 'december';

my @refMonth = (
    \$rm1, \$rm2, \$rm3, \$rm4,  \$rm5,  \$rm6,
    \$rm7, \$rm8, \$rm9, \$rm10, \$rm11, \$rm12
);

print ${$refMonth[4]}; # may
  • 配列 @refMonth の5番目に入っているスカラーのリファレンス
    • わかるかぁっ!
      • 書いてみると分かる
  • 苦しい、こうやって解釈していくの苦しい。慣れるもんなんだろうか。

すばらしい「ぶつぶつコンンピュータ」

  • この章、配列のリファレンスを1行ごとに解説する「ぶつぶつコンンピュータ」、つまりPerlを実行するコンピュータの気持ちになってリファレンスを紐解いていく下りがあるんだけど、これが良い
    • くどいけど良い
  • うちのような初学者には、これが本当に理解の助けになる。
  • 例えば、 $month->[2][0] ってリファレンスについて
  • month という名前があるなー
  • 前に $ があるからスカラーだなー
  • 後ろに -> があるから $month はリファレンスだなー
  • $month->[2] ということはリファレントは配列で、その第3要素を返せばいいなー(配列インデックスはゼロ始まりだからなー)
  • さらに [0] があるから、 $month は別の配列へのリファレンスで、そのリファレントの第1要素を返せばいいなー
  • これを追体験していく事で、ほんと理解が深まるんだよなぁ。
  • 全編これだと本のサイズがふくれあがっていくらページあっても足りないし、くどいけど

無名感、即時感

  • 無名配列、書いてはいるので、何となく分かる
  • 分かるけど、どう、「無名」なのかがずっと引っかかっている
    • アクセスするときは配列名がないため、リファレンス通しており、リファレンス名は配列名ではない・・・ってのは分かる・・・よ
  • anonymous っていうと、今時だとあのガイ・フォークスの仮面思い出しちゃう

  • そこに(勝手にうちがメンターとして仰ぎ見てる)@xtetsujiさんが助け舟を

  • 無名感!即時感!こっちの方がしっくりくる。なるほど。
    • Javascript で「無名関数」を「即時関数」って言ってる本があったなそういえば
    • いちいち配列名をつけず、そのまま配列作ってしまう即時・即席感