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 で「無名関数」を「即時関数」って言ってる本があったなそういえば
    • いちいち配列名をつけず、そのまま配列作ってしまう即時・即席感

すぐわかる オブジェクト指向 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 本にしようかなぁ

かんたんPerl 第11章 正規表現

おなじみ正規表現

  • とはいえ、全くしらなかったのがこれ
use 5.012;
use warnings;
use utf8;
binmode STDOUT, ':encoding(UTF-8)';

while(<DATA>){
    chomp;
    say $_ if /\d/;
}

__DATA__
1
2
3
0  #全角のゼロ
  • なんと、これ実行すると「0」も表示される。
  • まさか、全角の数字まで \d 文字クラスの数字にマッチするとは・・・
  • ただし、 utf-8 プラグマ利用時
    • これは、Unicodeの文字プロパティを使った文字クラスになるため。
    • /\d/a とすることで、半角数字にマッチ、とする事が出来る。

かんたんPerl 第8章 自作関数サブルーチン

ダイクストラ法!

適切な機能の切り出し方

  • サブルーチンについてはだいたい分かるのだけど、自作スクリプトにおける「適切な機能の切り出し方」ってのがイマイチで
  • 細かすぎても、おおざっぱすぎてもダメで、そういうあたりがプログラミングのセンスってやつなのかなぁと思ったり。