sironekotoroの日記

Perl で楽をしたい

オブジェクト指向Perlマスターコース 第1〜2章

「遅れてきた自分」が感じる Perl の素晴らしさ

  • うちのように齢 30 超えてプログラムに興味を持った人にとっては、Perl はとても良い選択
  • なんせ、「枯れた言語」であるので、大昔の本でも今に生かせる知識がある
  • 他にも枯れた言語はあるけど、すぐに実行できて、分かりやすく、コミュニティ活動があり、未だに web の第一線で使われている、という Perl の有り難さがある

ということで「オブジェクト指向Perlマスターコース」

  • 先に学んでいた「すぐ分かるオブジェクト指向Perl」で参考書籍にあげられていた本
  • Amazon では新刊は入手できず、マーケットプレイスで入手
  • 「枯れた言語」だと参考書籍も安く上がってありがたい
    • でも、申し訳なさもある・・・著者の方には一銭も入らないわけだし
    • Perl 本の新刊はちゃんと買うようにしているんだけどね
  • 正直、!5年前(2001年)に出た本を買うのは勇気がいったが、ま、買わない事には無駄かどうかも分からない
  • 1つ得るものがあって、ずっと生かす事が出来れば、安い投資である

第1章 オブジェクト指向入門

概念 別名
オブジェクト クラスインスタンスインスタンス変数
クラス ユーザー定義型、オブジェクトテンプレート、メタオブジェクト、パッケージ、モジュール
オブジェクト属性 フィールド、スロット、インスタンス変数、メンバオブジェクト、データメンバ
クラス属性 クラス変数、クラスフィールド、インスタンス変数、メンバオブジェクト、データメンバ
オブジェクトメソッド インスタンスメソッド、セレクタ、ハンドラ、メッセージハンドラ、フィーチャ、メンバ関数、オペレーション、パッケージオペレーション
クラスメソッド 静的なメソッド、静的なメンバ関数、共有メソッド
メソッド呼び出し メソッド起動、メッセージ、イベント
インターフェイス プロトコル、機能集合
継承 サブクラス化、クラスの特殊化、導出
カプセル化 データ隠蔽、データプライバシー
総称クラス テンプレート、パラメータ化クラス、総称パッケージ、総称モジュール
多態的メソッド 仮想関数、総称メソッド、優先オペレーション、メソッド
抽象メソッド 純粋仮想関数、延期機能
スーパークラス 親クラス、基底クラス
サブクラス 子クラス、派生クラス
  • まぁ、正直言うとこの表みたときに感じたのは「殺意」
  • こんなに別名多いのかよ!
  • なるほど、Web から拾い読みしてただけでは用語が混ざって、一生オブジェクト指向わかんないなぁ
    • 今だったらもっと増えてそう

第2章 Perl入門

  • この辺りはさらっと
  • 今までの積み重ねが生きてる感
  • とはいえ、 wantarray はサブルーチンからの返り値チェックに積極的に使っていきたい
sub subroutin {
    return wantarray();
};

my $scalar = subroutin();
print $scalar , "\n"; # ""

my @array = subroutin();
print @array , "\n"; # 1

  • 型グロブの存在意義、今まで全く理解できなかったんだけど、以下の説明で腑に落ちるところがあった

しかし型グロブでは、さらにもう1つの重要なテクニックとして、選択的に割当を行う 事が出来る型グロブに様々な種類のリファレンスを割り当てた場合、対応する種類の型グロブのスロットのみが置換される。
perl *SOURCE = \$SOURCE1; *args = \@ARGV; *do_it = sub {print "coin' it!\n"}; つまり上記3つの割り当てで、$SOURCE$SOURCE1 の別名になるが、 @SOURCE , %SOURCE , &SOURCE などは影響を受けない。同様に、 @args@ARGV の別名になり、 &do_it は無名サブルーチンの別名になる。
(中略)
この割り当ての動作はポリモーフィズムの一例である。つまり、刺激(割り当て)は常に同じであるが、反応(型グロブで実際に変更される部分)は、割り当てられている値のデータ型に依存する。

最近のPerlの勉強とか:2016年06月

最近やっている事

  • 「すぐわかるオブジェクト指向Perl」を読み終えた後、既存の自作プログラムの改修をやっておりました
  • RSSフィードを持ってきて、自分の好きに変形して出力するもの
  • 以前に作ったものはこういうもの
    • 再利用性考えてないので、1つのRSSフィードに1つのスクリプトで対応
    • モジュールはネットに書いてあった例をコピペ、又はそれにして毛を生やした感
      • それでもちゃんと動くんだからたいしたもの
    • 機能ごとにサブルーチンに分割してある
      • 他のRSSを処理する時はサブルーチンをコピペ
      • しかし、作成時期により微妙な差異がある
    • VPS上の cron でうまく動かなかったので、 シェルスクリプトに起動スクリプトを書いて、そこから Perl スクリプトを呼ぶという謎仕様
  • これを以下のように変更
    • オブジェクト指向で作り直し
    • 共通した処理である、RSS取得 , パース , Atomへの変換 , 出力 をメソッドで実装
    • RSSフィードごとに異なる再構築部を個別で実装
    • プロパティの取得と変更はちゃんとセッター、ゲッター経由で実施
    • cron から直接スクリプトを呼んで実行させる
      • cron から plenv で入れた Perl にパスが通っていなかった事に気づき解決

作りなおしてみて

  • RSSフィードごとに異なる部分と共通処理部分を分離する、というのが実現できて嬉しい
    • さらに楽
  • オブジェクトの中のデータをメソッドでグニグニするという感覚を得る事が出来た
  • それは既に Time::Piece とか Web::Scraper で使わせてもらっていた事ではないか!という気づき

これからのPerl勉強

  • 他の既存プログラムの改修
  • さらなるPerlの勉強
    • 職場の昼休み中に結城先生の「Perlクイズ」を1日1問ずつ
    • 土日に集中して・・・何をやろうかねぇ。以下の本が候補なのだけど
  • あと、テストを書く習慣が無いので、身につけないとなぁ
    • いまは Data::Dumper 使って say Dumper $hogehoge 頼み
  • PerlTidi 頼みなので、ちゃんと Perl Best Practice 読む
  • それに、そろそろ仕事で本格的に楽をするためのプログラム組みたい・・・
  • 楽をして儲かるとなお良い・・・
  • やりたい事いっぱいだ!

そういえば

  • 昔を思い出す
    • オブジェクト指向?知らなくても動くプログラム作れるよ」
    • 「リファレンス?知らなくても動くプログラム作れるよ」
    • 「ハッシュ?知らなくても(略」
  • そんなふうに考えていた時期が俺にもありました
  • 構造や働きをまとめることで結果、楽をする事が出来るって素晴らしい事なんだよなぁ
  • きっともっと楽をしたり、出来る事が広がる知識があるはず
  • なにより、「俺の考えた最強のプログラム」作って動かすのはとても楽しい!

One More Thing

  • Javascript も勉強してたけど、自作Perlスクリプトを作り直すのが楽しくて手を付けてなかったので再開させる

すぐわかる オブジェクト指向 Perl 第13章 オブジェクトクラスの継承、デストラクタ、永続化

オブジェクトクラスの継承

  • これは分かる。
  • イメージしやすい
  • 抽象的なものはどんどんスーパークラスに集めて、具体的なものだけを普通のクラスにしてスーパークラスを継承、ってすると良いのかな

デストラクタ

  • オブジェクトが破棄されると呼び出されるメソッド
    • どんな使い道があるんだ?

      書いてもいいし、書かなくてもよい

    • なるほど

オブジェクトの永続化

オブジェクトの永続化は DESTROY でオブジェクトの中身をファイルに書き出し、 new でファイルからオブジェクトを再構築するとスマートです

  • スマートっていうか、割と原始的感ある
    • でも、確かに、この方法であれば、プログラムを終了してもデータは永続化できるなぁ
  • と思ってたら Storeble モジュールの話が出てきた
  • さらに、 Data::Dumper でデータを永続化する方法も

読み終えた・・・まだ残ってる

  • 第14章はCGICPANのお話なので、これは読むだけで飛ばすと。
  • いや、やっぱCGIのところはやっておこう
  • CGI久々すぎて、Apacheの起動の仕方忘れてた
    • XAMPPのツールから起動
    • そろそろ nginx も触ってみたいけど怖い
    • それいうなら、AWS で EC2 とかも  - いや、その前に GAS で
    • やりたい事大杉
  • シバンをつけるの忘れてた
  • chmod でパーミッション変えるの忘れてた

CGI

  • 思えば、CGI.pm で table 作ったのはじめてだ
  • 動かせた
  • 共用サーバとかで、 Apache のエラーログが見られないときには、 use CGI::Carp すると。なるほど。

「すぐわかる オブジェクト指向 Perl」を読み終えて

  • 何だろう、とてもじんわりと感動してる
  • ずっと憧れてきた「オブジェクト指向プログラミング」を素材から触れて行く感覚が良い
  • 「続・はじめてのPerl」読んでもよく分からなかったけど、まぁ、オライリーの本は復習用・到達度確認用と思うことにする
    • 今読んだら、最初に読んだ時よりもずっと深く理解できる気がする
  • 不思議と、今までのプログラミングでは感じることが無かったのだけど、この本でオブジェクトを作っている時は、「俺は今このプログラムの神なんだ」という不思議な感覚があった
    • そして、業務で出会う「出来のよろしくないプログラム」に思いを馳せたり
    • 「神様」のレベルや、想像力が無いと出来上がるものもそれなりだよね、って
  • そんで、 cpan などで見つけたモジュールで、既に hogehoge->new とか、オブジェクトを使っていたんだな、という感慨が新たに。
    • ずっとそばにいたんだなぁと
  • 読んでよかった、挑戦してみてよかった
  • 一通り初心者本を読んで、次のステップに飢えていた、でも「続・はじめてのPerl」は難しいという自分にぴったりだった
  • 後は自作のスクリプトでどう生かすか、だよなぁ
  • まだまだ勉強は続く

すぐわかる オブジェクト指向 Perl 第12章 演算子のオーバーロード

おぉ

  • 前章で作ったセッターとゲッターをひとつのサブルーチン(メソッド)にまとめる。
  • セッターかゲッターかは、呼ばれた時の引数の数で判断する
  • かっこいい!無駄が無い!クール!

うおお・・・

  • 演算子オーバーロードで、同じオブジェクトでも別な内容を応答する、という例題
  • 数字を期待されているのか、文字列を期待されているのか、というのをオブジェクト自体が判断して適切な値を返す、ようにオーバーロードを設定する
  • 正直、自信無い、凄すぎる・・・
use overload
    '""' => "toString",
    '0+' => "toNumber";


sub toString {
    my $self = shift;
    my $a    = $self->{a};
    my $b    = $self->{b};
    my $c    = $self->{c};
    return ("($a,$b,$c)");
}

sub toNumber {
    my $self = shift;
    return ($self->{s});
}
  • 抜粋して書くとこう。
  • うん、正直使いこなせる気がしねぇ・・・

すぐわかる オブジェクト指向 Perl 第11章 オブジェクト クラスの作成

-> は左結合

  • なるほど
  • $space = Triangle->new(3,4,5)->InscribedCircleSpace;
    • この場合には、Triangleメソッドに 3 , 4 , 5 って値を与えて三角形オブジェクトを作成して、その内接円を求める
    • おぉ、なんかかっこいい

!?

一方、クラスは型のことです。
少年漫画「翔丸」(能條純一著、講談社刊)では、さっきまで無軌道に暴れていた怖いお兄さん達が、謎の美少年・翔丸によってナイフで傷を付けられる事によってすっかり型にはめられてしまい、軒並み「翔丸組」の軍門に下ってしまいます。

  • いきなりの能條画伯の登場にビビる
    • 次のページにワンカットもある
  • こんな展開を550ページの本の350ページまで隠しておくとは・・・
  • 翔丸 - Wikipedia

    翔丸』(しょうまる)は、能條純一による日本の漫画。『コミックモーニング』(講談社)において1987年13号から1989年6号に掲載された。当初は不定期掲載、のちに隔週連載。同じく能條の『天の男』や『ゴッドハンド』に見られる「悪のカリスマ」を描いた系統の作品である。

  • 知らないなぁ・・・
    • 絶版本を置いているマンガ図書館Zには無かった。漫画喫茶ならあるかな?

ここでは「翔丸組」がクラスで、翔丸が振るうナイフがコンストラクタと考えられるでしょう

  • わかんねぇ・・・けど、分かるような・・・
  • ナイフでシャってやる事でクラスを作る、的な?

クラスとオブジェクトの関係はよく人形焼きに例えられます。人形焼きというと鯛焼きとかペコちゃん焼きの仲間で、皮とアンコを型に入れて焼くと、中から七福神などの形をしたお菓子が出てきます。
ここで人形焼きを作る機械をコンストラクタ、いっこいっこの人形焼きをオブジェクトというわけです。

オブジェクトは、あるクラスのコンストラクタによって、そのクラスのオブジェクトとして生成される

  • ううん、わかったような。
  • 鯛焼きは、鯛焼き機によって、鯛焼きになる・・・?んん?

# クラスとインスタンスとオブジェクト

クラスもまたオブジェクトである

  • なるほど、先の「鯛焼きは、鯛焼き機によって、鯛焼きになる」で??ってなったのは、こういうことか?

クラスがオブジェクトに与える要素のことをプロパティ(property 属性)といいます

メソッドは、オブジェクトに渡すメッセージであるという言い方をしましたが、メソッドには2つの目的があります。 - プロパティを取得する - プロパティを設定する

  • おっけー、これは分かる。

三角形型の操作も同じ原理です。「三角形さん、あんたを 3 , 4 , 5 という辺の長さで生成するよ」というコンストラクタメソッドの一種で、1つのメッセージ渡し(message passing) です。

  • うん、わかる、納得できる。

bless で classに神の祝福を

  • いろんなところで見てきて、いろんな本で見てきた bless が何をするものなのか、やっとわかった

    • インスタンスメソッドで作ったリファレンスが、どのクラスに属しているかをリファレンスに分からせる・・・
    • ちゃんとした言葉で言えないところに理解力不足を感じる
    • でも、分かった感はある、Perlオブジェクト指向の勉強してはじめて、分かった感がある。
  • ためしに、「続・はじめてのPerl」のOOPのところをさらっと読んでみると、わかる。

    • ただただ本を写経していたけど、今は、その意味が(なんとなく)わかる。
    • ここで、「続・はじめてのPerl」に行きたい気持ちを抑えて、本書を続行する。
    • というか、自作のオブジェクト作ってみたいすぎて

ゲッター、セッター

  • はい、これもイミフな単語でした。
    • はじめて聞いたのは、たしか YAPC::Asia2013 でだった気がする
    • よくそんなんで参加したなと思うが、参加したおかげで今があるので、積極的に参加するべき
  • オブジェクトのプロパティ?「直接いじれば良いじゃん」とか思ってたので反省。

    特に重要なのは、セッターで不法な値を代入したときに croak することです。

唐突に

  • あぁ、そうか、オブジェクトがデータと手続き(操作)を一緒に持ってるって、こういうことか
  • エウレカエウレカ

すぐわかる オブジェクト指向 Perl 第10章 静的クラスの作成

9章はみるだけー

  • 9章で参考にしている Calender というモジュールが CPAN からダウンロードできないみたいなので、見るだけ。

やってきましたオブジェクト指向

  • 構造化プログラミングで再利用部分をサブルーチンにくくりだす:ok
  • 再利用部分をファイルで分けて、モジュール化する:ok
  • ファイルをまたいで、サブルーチンを呼び出す:ok
    • &package名::subroutin(@ARGV)
    • 受け側には 引数(@ARGV) だけがわたる
  • メソッド呼び出し:ok
    • package名->subroutin(@ARGV)
    • 受け側には、パッケージ名と@AGRV がわたる
    • 矢印記法で呼び出されたサブルーチンをメソッドと言う
    • メソッドを持っているパッケージをクラスという
    • パッケージ名は第一引数となり、これをインボカント(invocant)、呼出し元という
      • 呼び出すは invoke
  • クラスの継承
  • AUTOLOAD
    • 継承元をさかのぼってもメソッドが見つからなかった場合にカバーしてくれる
    • 存在しないメソッドの完全修飾名が $AUTOLOAD に入る
    • サブルーチンの実装忘れもこれで安心(違
  • 継承されるのはメソッドだけ
    • 変数は継承されない
  • use base qw(package) 、1モジュール1パッケージでスッキリ
    • あまり複雑な事はしないようにしよう・・・
  • is a
  • SUPER クラス

正直なところ

  • 継承とオーバーライドについてはok
  • でも、is a とかについては実際に使えるんかな、って気がする。
  • 正直、メソッド呼び出しをしてパッケージ名がサブルーチンに渡されるメリットが分からない。
  • 以上が今の到達地点
  • とりあえずこのまま進めて、分からなかったらまた戻ってこよう。

すぐわかる オブジェクト指向 Perl 第8章 モジュールを使う use

モジュールのバージョン

  • @EXPORT$VERSION 変数を指定しておく事でモジュールが use した時のチェックを行う事が出来る、と
  • モジュール側で
package hogehoge;
our @EXPORT = qw($VERSION);
our $VERSION = "1.0";

としておいて、呼び出し側はこう

use hogehoge 2.0;

とするとエラーになる

おなじみ use

  • use strict よく使うというか必須だよね
  • しかし、そこで何をしているかは考えた事も無かった・・・

    use モジュール名;
    という1つの文は、次の4行のプログラムと全く同じ動作になります。
    BEGIN {
    require モジュール名;
    import モジュール名;
    }

  • なるほど

  • つまり use はモジュールを読み込んで、さらにモジュール内の変数やサブルーチンを import すると
    • そのまんまやねん

うなる

変数は my をつけてレキシカル変数にする事で完全にプライバシーを守れ、モジュール外から見る事ができなくなりますが、サブルーチンだけは完全修飾名を使う事でモジュール外から見る事ができてしまいます。では、モジュール外からアクセスできないサブルーチンを定義する事はできるでしょうか?

答えは、できます。ちょっと難しい話ですが、ここまでの知識で答えられるのでちょっと考えてみてください。
はいおわかりですか。無名サブルーチンリファレンスを使って、それをmy変数に代入すれば良いですね。
これをプライベートメソッドと言います。

  • なるほど!