sironekotoroの日記

Perl で楽をしたい

すぐわかる オブジェクト指向 Perl 第6章 、第7章

第6章 ライブラリを取り込むrequire

なるほど

  • リストの要素である、数字の重複を排除する、というサブルーチン uniq
my @arr = ( 5, 4, 7, 4, 5, 7, 4, 3 );

sub uniq {
    my @in = @_;
    my %out = ();
    foreach my $in (@in) {
        $out{$in} = 1;
    }
    my @return = keys %out;
}

print uniq(@arr); #4375
  • 配列をハッシュの key にして、その値に固定値で1を入力する。
    • よくある
    • でも、プログラムを学ぶ前だと分からなかったと思う。
    • 準備された uniq 関数を使う事は出来ても、それを自分で実装できたかどうか・・・自信ない

「なんでもかまわない時は1」というのは Perl 仲間の間で、ゆるやかな合意として成立しているので、他の人がリストを読んだとき「ああ何でもかまわないから1を入れたんだな」とわかります

  • この「1」ってのは、モジュール作ったときに最後に入れる「1」と同じなんかな?
  • おいおい出てくるだろう

ライブラリ

次に arrUtil というライブラリを作っていきます。ここでライブラリ(library)とはサブルーチンを集めて色々なプログラムで呼び出せるようにするファイルの事です

  • ライブラリの説明って以外と無かった気がする。
    • もちろん、うちが覚えていないだけの可能性大

小ワザ

print join "\n" , @INC;
  • ライブラリがおいてあるフォルダを表示するものなんだけど、なるほど、join をこうやって使うのか、と。
    • うちだったら、配列だから foreach つかって〜・・・ってなってたと思う。迂遠
  • そして @INC の中に、 . があるから、カレントディレクトリ内のファイルもライブラリとして実行できるんね

第7章 名前空間を作るパッケージ

  • my で変数を宣言する、という事がその変数の呼び出せる範囲を規定する事、つまりオブジェクト指向における「カプセル化」を担う・・・
  • なるほどなぁ!何も考えずに、マナーとして my を使ってきたんだけど、なるほど。
  • だもんで、 our で宣言する変数の使い道?とかよく分かってなかった。
  • いやー、勉強になる!勉強してるんだから当然だけど、勉強になる!

すぐわかる オブジェクト指向 Perl 第4章 、第5章

ハッシュスライス!

  • 「第4章 ハッシュのリファレンス」については特に引っかかりなくすらすらと
  • いや、一個だけあった、ひっかかったところ
$refMonth = {
    January   => 1,
    February  => 2,
    March     => 3,
    April     => 4,
    May       => 5,
    June      => 6,
    July      => 7,
    August    => 8,
    September => 9,
    October   => 10,
    November  => 11,
    December  => 12,
};

for( @{$refMonth}{ September, October, November } ) {
    print "autumn contains month No. $_\n";
}
  • @{$refMonth}{ September, October, November } 、普段ハッシュスライスを使わないので、初見で???だった
    • ハッシュスライスを使うべきところで、迂遠な書きかたしているなぁって思った
    • 知っていれば回避できる苦労、知らないと回避できない苦労
    • 学習大事よね

サブルーチンリファレンスがあるなら、サブルーチンは

  • 「第5章 サブルーチンのリファレンス」
  • サブルーチンもリファレンス化出来るなら、普通の(今まで学習してきた)サブルーチン構文とはいったい・・・って気持ちに
    • サブルーチンのみならず、(普通の)配列も(普通の)ハッシュも、リファレンス化したものの前座なのだろうか・・・

シグナルハンドラ

ここでは Perl であらかじめ定義された特殊なハッシュ変数 %SIG というものを紹介します。この要素にサブルーチン リファレンスを入れると、プログラムが OS の機能によってあるシグナルを受け取ったときに、そのシグナルによってサブルーチンを実行します。

  • $SIG{'INT'} = sub {print "Oh, you pushed Ctrl-C! \n"}
    • Ctrl + C を押したときに、 `SIG{'INT'} が呼び出されて、そのときハッシュの値に格納されたサブルーチンが動く、という理解で良いのかな?

この行では、ハッシュ要素 $SIG{'INT'} に無名サブルーチンを代入しています。これによって、このプログラムが sigiht をもらったときに実行する動作を定義しています

  • 通常は Ctrl + C でプログラムの実行を止める sigint になるけど、その動きを上書きして制御できると。
  • なるほど!

シュワルツ変換

  • まず名前がかっこいい
    • 大昔、シナリオシュミレーションゲームで「シュバルツシルト」ってゲームありましたなぁ
  • たしか「続・はじめてのPerl」にも出てきた
  • その時はふんふん、なるほどーで通り抜けた程度
  • しかしこの本はみっちり解説がついている
  • 詩を、各行の長さ順で並べ替えるという例題
    • その1:各行の文字列の長さを配列に入れ、それを sort
my @input = <DATA>;
my @length = ();

for (@input){
    push @length , length($_)
}

print sort {$b <=> $a} @length;
  • その2:各行そのものの文字列と、文字列の長さを配列に入れて、リファレンス化し、それを別な配列に入れる
for (@input) {
    my @lengthIndex = ();
    $lengthIndex[0] = $_;         # 文字列そのものを配列の0番目に
    $lengthIndex[1] = length($_);   # 文字列の長さを配列の1番目に
    push @length, \@lengthIndex;
}
  • その3:(その2で用意した)配列リファレンスを、文字列の長い順に並べ替えて、さらに別な配列に格納
    • 一応これで例題は解ける
my @length2 = sort {$b->[1] <=> $a->[1]} @length;
for (@length2){
    say $_->[0];
}
  • その4:最初の for 内で利用している配列を無名配列にする

    • なるほど、確かにこの @lengthIndexfor の中でしか使っていない、「使い捨て」の配列だ
    • これぞ無名配列!これこそanonymous Array !納得した!
  • その5:2回使われている foreachmap で置き換えていく

my @length = map { [ $_ , length($_) ]  } @input;
my @length2 = sort { $b->[1] <=> $a->[1] } @length;
print map {$_->[0]} @length2;
  • その6:mapUNIX のパイプのように書けるので、中間配列が不要になる
    • ついでに不要なコードブロックも外す
print map $_->[0], 
      sort { $b->[1] <=> $a->[1] }
      map [ $_, length($_) ], @input;
  • 美しいなぁ・・・

すぐわかる オブジェクト指向 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 で「無名関数」を「即時関数」って言ってる本があったなそういえば
    • いちいち配列名をつけず、そのまま配列作ってしまう即時・即席感

すぐわかる オブジェクト指向 Perl 第2章 「参照」は小粒でピリリと辛い 〜 スカラー リファレンス 〜

スカラーリファレンスで1章まるまる?

  • リファレンスについては「どういうものか」は分かるんだけど、スカラーリファレンスって使い道あるんかな・・・?
  • という疑問を持ちつつ本を読んでいく

今の時点で理解している「リファレンス」

  • 変数がおさめられているメモリ上の番地
  • 配列やハッシュもリファレンスにするとスカラーとして扱う事が出来る
  • 配列の中に配列、ハッシュを入れる事は出来ないが、スカラーなら入れられる
  • だからリファレンスにしてスカラーにする事で、配列の中に(リファレンス化した)配列やハッシュを入れる事が出来るようになる
  • リファレンス化した配列やハッシュを元に戻すには「デリファレンス」を行う

!?

$refAge = \14;

print "refAge is $refAge and it contains $$refAge \n";
# refAge is SCALAR(0x7fddf201ad10) and it contains 14

$refName = \"Robin";

print "refName is $refName and it contains $$refName \n";
# refName is SCALAR(0x7fddf201ae78) and it contains Robin
  • $refAge = \14 こんな書き方も出来るのか
    • メモリ空間に直接数値を入れ、そこへのリファレンスが生成されると

スカラー変数のリファレンスはあまり役に立たない

  • ですよねー
  • 次章以降の配列、ハッシュ、サブルーチンリファレンスが楽しみ

すぐわかる オブジェクト指向 Perl 第1章 いきなりモジュールを使ってみる

いよいよPerlオブジェクト指向

  • さすがにPerl初心者本も狩り尽くしてきた感がある

    • 未読のPerl初心者本はまだまだたくさんあるのだけど、2000年以前の本など古いものが多い
    • それに何より飽きた
    • そろそろ自分で作ってる現世利益なプログラムに変革をもたらす、何かが欲しい!
    • OOPで書かれてるモジュール解読してみたい!
  • という事で、「続・はじめてのPerl」で???となったオブジェクト指向を学ぶべく次の本を手にしたのだった。

    • 2014年3月5日発行の第2版

  • でも、オブジェクト指向に期待をかけすぎるとツラいらしいんで淡々と、いつも通りやっていきまする

第1章 いきなりモジュールを使ってみる

  • 目次をみると、オブジェクト指向に至るまで結構長い
  • 復習がてらこなしていく
  • あせらず、じっくりねっとり行く
use File::Find;

find( \&fileproc, '.' );

sub fileproc {
    print "$File::Find::name\n";
}

  • この、わずか5行のプログラムから疑問を見つけ、掘り起こし、それを後の章で解説するという構成みたい

  • そして1章の後にあるコラムにうちの持ってる心配・疑問に関しての答えそのものがのっててビックリするなど。

    • 原価 + 消費税分 の元はこのコラムだけでとれた。
    • 知らない事があっても別に平気!

Perlマスターブック Perl5.6/5.8対応

今の自分にちょうど良い

  • 思いがけぬ残業で荒んだ気持ちで帰る途中、bookoffで見つけたのがこの本

  • Windows 環境からのインストール、変数、制御構造、サブルーチンなど一通り

  • さらにオブジェクト指向にも一章を割くなど
  • 初心者本からオブジェクト指向Perl本へ行こうとしていた自分にはちょうど良い
    • しかし、今日の夜にも次のPerl本がくるので駆け足で攻略!

かけあし

my @array = ('a'..'z');
# abcdefghijklmnopqrstuvwxyz

say @array[1,4];
# be

my @temp = (1,4);
say @array[@temp];
# be
  • うむ、つまり、配列のスライスに配列がとれる(という言い方で良いのかな?)
  • あと、連想配列のスライスをもっと自分のスクリプトで使ってみたいんだけど・・・使う事が出来るところはいっぱいありそうなのだけど

  • Chapter5: 制御構造

    • continue文ってどういう利用シーンがあるんだろ・・・想定できん・・・
  • Chapter6: リファレンス

    • ハードリファレンスって言い方は初めて見たかも
    • 無名配列、無名連想配列・・・かつては???だった
      • 配列としての名前はない(無名)けど、リファレンス名はある、と理解
  • Chapter7: ファイル操作、文字列操作、日付関数
  • Chapter8: サブルーチン、モジュール
  • Chapter9: 正規表現
  • Chapter10: 変数のスコープとシンボルテーブル
    • 型グロブ: 同じ名前を持つデータ構造を管理する形式
      • なるほど!
  • Chapter11: サブルーチン
  • Chapter12: パッケージとモジュール
    • use は BIGINサブルーチンと同じタイミング、メインスクリプトよりも先にロードと実行が行われる
    • require は メインスクリプトの読み込み時にロードと実行が行われる
    • use strict ではシンボリックリファレンスが禁止されている
      • この本の出版時で既に推奨されていない
      • なるほど、知らぬ間に use strict に救われていたんだなぁ
  • Chapter13: オブジェクト
    • オブジェクトとは、パッケージにひもづけられた・・・変数とサブルーチン・・・
    • ぷしゅー
    • とにかく、いろいろ作って、体得していこう
    • Universal クラスは組み込みで準備されている

かんたんPerl 第12章 モジュール入門/フォルダー処理、CGI

いよいよ最終章

  • CPAN は シーパン 読み派
  • File::Find つかってるけど、このモジュール、「続・はじめてのPerl」でも使ってたし、なにか定番というかお約束なのだろうか。

CGI

  • 大昔、CGIの本を手に取った事もあったんだけど、さっぱり分からなかった。
  • 何が分からないかというと、Perlでの処理の結果をどうApacheに渡すのか?あるいは逆ということ。
  • 表の HTML と裏で動いているプログラムが OS の環境変数使って値をやり取りしている、ということが理解できるようになるには、いろんな偶然が必要だったなぁ、と思う
    • Linux のサーバ運用の仕事に就いた、とか
  • というか、簡単なWeb掲示板を実現するにも、CGI/Perl , Apache , OS の知識が必要で、割とハードル高いんよね・・・

さて次は

  • 何の Perl 本にしようかなぁ