ドキュメントをどうするのか

ドキュメントを書かない理由

ドキュメントはそれがなくても正しく動いてしまうため、
プログラミングして成果物を動作させるという観点からすると後回しにしてしまいがちです。

そのため、実装とずれが出がちになり、出すぎると更新するのも嫌になってきます。

これも一つの割れ窓理論ですね。

そして、そうなるくらいなら、ドキュメントを書かずにPerlベストプラクティスを参考にきれいな実装をして
ドキュメントレスを目指そうとしていました。
実は単なる面倒くさがりなだけなんですよね。

達人プログラマーでもPerlベストプラクティスでもドキュメントの重要性が説かれているのに
それに目をつぶってまで、面倒くささを回避することの方が重視されていました。

心のどこかで、ドキュメントは重要なのに。と、後ろめたさでいっぱいです。

PODも単体テストに組み込みましょう

保守性の観点からもドキュメントは重要です。

この記事を読んでいる方は保守性の高いプログラムという言葉も好きな方だと思います。

  • 保守性を高めるため、
  • 頻繁に更新されるドキュメントを、
  • プログラミング作業とシームレスに

行う方法はないのか?

ありました。答えはpodの埋め込み+Test::Pod+Test::Pod::Coverageです。

まずは、Test::PodとTest::Pod::Coverageをインストールしてください。

あとは、

98_pod.t
      • -
use Test::More; eval "use Test::Pod 1.14"; plan skip_all => "Test::Pod 1.14 required for testing POD" if $@; all_pod_files_ok();

および、

99_pod-coverage.t
      • -
use Test::More; eval "use Test::Pod::Coverage 1.04"; plan skip_all => "Test::Pod::Coverage 1.04 required for testing POD coverage" if $@; all_pod_coverage_ok();

を、tディレクトリに放り込んで、MANIFESTに追記してください。
この状態でテストをはしらせると、

$ make test
PERL_DL_NONLAZY=1 /usr/local/bin/perl5.8.9 "-MExtUtils::Command::MM" "-e" "test_harness(0, 'blib/lib', 'blib/arch')" t/*.t
t/00_compile.t ....... ok
t/98_pod.t ........... ok
t/99_pod-coverage.t .. 1/1
#   Failed test 'Pod coverage on Foo::Bar'
#   at /usr/local/lib/perl5/site_perl/5.8.9/Test/Pod/Coverage.pm line 126.
# Foo::Bar: couldn't find pod
# Looks like you failed 1 test of 1.
t/99_pod-coverage.t .. Dubious, test returned 1 (wstat 256, 0x100)
Failed 1/1 subtests

Test Summary Report
                                    • -
t/99_pod-coverage.t (Wstat: 256 Tests: 1 Failed: 1) Failed test: 1 Non-zero exit status: 1 Files=3, Tests=3, 0 wallclock secs ( 0.03 usr 0.01 sys + 0.05 cusr 0.18 csys = 0.27 CPU) Result: FAIL Failed 1/3 test programs. 1/3 subtests failed.
Error code 1
見事に単体テストでこけました。 これで、PODをちゃんと書かないと正しく動かなくなりましたね。(開発プロセスが) これがイイんです。慣れると make test の Result: PASS が気持ち良くなってくるんですが、
  1. 実装する。
  2. PODを正しく更新しないと気持ち良くなれない!
  3. ちゃんとPODを更新する。
  4. 保守性が確保できる。
  5. 後ろめたくない。(開発に専念できる)1に戻る。
という、良いループができます。

PODを書く

では、PODを書きましょう。 まずは、Perlベストプラクティス(7.2 ひな形)を参考にして、適当に項目を選択しテンプレートファイルを作成します。 私はNAME,SYNOPSIS,DESCRIPTION,METHODS,SEE ALSO,AUTHOR,LICENCE AND COPYRIGHTを採用してます。 この辺は、慣れてから調整したらいいかなと思います。あんまり多いと書く気が失せますし。 またvimを使っていますので、Perlベストプラクティスにあったiabを設定しました。 NAMEのところで、今回の場合はFoo::Bar - モジュールの説明を書けば、
$ perl Makefile.PL PREFIX=~/local/perl
Checking if your kit is complete...
Looks good
Writing Makefile for Foo::Bar
前回と違って警告がでなくなりました。
$ make
cp lib/Foo/Bar.pm blib/lib/Foo/Bar.pm
Manifying blib/man3/Foo::Bar.3
$ make test
PERL_DL_NONLAZY=1 /usr/local/bin/perl5.8.9 "-MExtUtils::Command::MM" "-e" "test_harness(0, 'blib/lib', 'blib/arch')" t/*.t
t/00_compile.t ....... ok
t/98_pod.t ........... ok
t/99_pod-coverage.t .. ok
All tests successful.
Files=3, Tests=3,  0 wallclock secs ( 0.02 usr  0.02 sys +  0.08 cusr  0.15 csys =  0.27 CPU)
Result: PASS
すばらしい。テストが通りました。

まとめ

PODを書くことを開発プロセスに組み込むまでをまとめてみました。 実はまだ、よくわかっていないことも多くて、名前だけあって説明がない場合にエラーにするには、 all_pod_coverage_ok({nonwhitespace => 1});でいけそうな感じなんですがなぜかだめだったり、 継承しているときにドキュメントしていないのにOKになったりします。 でも、今まで書いていなかったことが書くようになったことは大きな前進です。 昨日より今日が良くなっていればとりあえずは良しとして今後の課題とします。

積読に気をつけよ

これまで、会社で購入してほしい本もなかなか切り出せず、
家では「仕事の本は会社で買ってもらえ!」となってなくなく小遣いから本代を出していた会社員時代。。。

それが、フリーで仕事をするようになってからは「必要なものは全部買っとけ!うひー」となりがちです。

あれもこれもと技術書を買いあさってもそれを消化するには時間がかかることを忘れないようにしましょう。

世に速読というものがあるそうで、幾度となくそういった本を読んでみましたが、全然身に付きません。

積読された本は、重いプロセスが積み重なったサーバがますます処理量を落とすように、
消化する読書量を減らすような気がしています。

まあ、でもやめられませんけどね。

先日も「WEB+DB PRESS vol.51」の巧いメソッド設計が気になって買いにいったのですが、

そこで「大人の科学 vol.24」にやられてしまいました。4ビットマイコンです。
気がついたら一緒に買ってました。

そしてまた、積み上げられていくわけです。

さくらのレンサバでPerlの環境設定

参考にさせて頂いたのは以下のサイトです。

iandeth. - 一般ユーザ環境におけるCPANモジュールの使い方

準備

前回(さくらのレンサバでbashとvim設定 - kuchimuraのメモ)までの設定で ~/localはできていますので、

[ユーザ名@ホスト名 ~]$ mkdir local/perl

で、モジュールのインストール先を作成しておきます。あとは、参考サイトのように、

[ユーザ名@ホスト名 ~]$ mkdir -p .cpan/CPAN
[ユーザ名@ホスト名 ~]$ cat >.cpan/CPAN/MyConfig.pm
$CPAN::Config->{cpan_home} = undef;
$CPAN::Config->{makepl_arg} = 'PREFIX=~/local/perl';
$CPAN::Config->{histfile} = "$ENV{HOME}/.cpan/histfile";
1;

cat はCtrl-dで抜けてください。

追記

重要なことが抜けていました。ここで、

[ユーザ名@ホスト名 ~]$ cpan

して、最後に

cpan[1]> o conf commit

してください。そうしないと、MyConfig.pmが上書きされないので、毎回設定する必要があるという憂き目に。。。

CPAN.pmのアップデート

いろいろ記事があったんですが、私の場合、上記のあと、いきなり

[ユーザ名@ホスト名 ~]$ cpan -i Bundle::CPAN

で、いけました。ミラーサイトの選択以外はデフォルトです。

モジュールやツール用の設定

モジュールをuseしたり、モジュールと一緒にインストールされるツールを使うために、

[uebuya@www1771 ~]$ cat .bashrc
source .profile

PATH=$PATH:~/local/bin:~/local/perl/bin

export LANG=ja_JP.UTF-8

export PERL5LIB=~/local/perl/lib/perl5/site_perl/5.8.9/mach:~/local/perl/lib/perl5/site_perl:~/local/perl/lib/perl5/5.8.9/mach:~/local/perl/lib/perl5

としました。.bashrcにPERL5LIBの追加とPATHの追加です。

PERL5LIBのmachは、未調査です。(Linuxi386-linux-thiread-multiみたいなものか?だとすると追加する必要ないはず)

2009-07-03追記

machの記述が間違っていたので修正。バージョン固有のディレクトリの下にあるっていうのはどういうこと?

linuxi386-linux-thread-multiみたいにアーキテクチャ固有のものはバージョン固有のものと同列にあるんじゃないの?

PERL_ARCH=machっていう風にFreeBSDports?とやらの設定で使うようだが??

よくわかりません。

Perlプロプログラマへの第1歩

はじめに

プロとしてのPerlプログラマが身につけておくべきことをつらつらと書いてみます。

対象読者は、(というより現在の私の状態でもありますが)

  • 達人プログラマーを読んで感銘を受けた。
  • が、そこから今実践できているのはDRY、割れ窓の心がけとソースコード管理くらい。
  • Perlプログラミング救命病棟でいったら、レベル7以上ではあることは自負しているがレベル8と言っていいのか迷っている。
  • モダンPerlプログラミング入門を読んで、モダンと自分の差にどっきりして、せめてテストとドキュメントをなんとかしようと思っている。
  • まあ、とは言っても理想にはなかなかなれないもので、日々努力して理想のPerlプロプログラマに漸近していくものと思い、やれるところからやりましょうか、といったスタンス。

です。

同じような境遇にあり、同感できる方がいらっしゃいましたら、一緒にステップアップしていきましょう。

なにはともあれCPAN形式

モダンPerlプログラミング入門で紹介されているようにCPAN形式で開発すると、
とても簡単に安定した開発プロセスを導入することができます。

じゃあ、どうやってCPAN形式で開発するか?というときにいろんな方法があるようですが、
私はh2xsを選択しました。

理由はすぐ使えるからです。
Module::StarterとかModule::Installとかは、CPAN形式になれて、どうしてもh2xsじゃつらくなってきてからでいいかな、と。

h2xs

$ h2xs -XAP --skip-exporter --use-new-tests -n Foo::Bar

これで開発プロセスを回すだけの一式ができます。上記の実行結果は

Defaulting to backwards compatibility with perl 5.8.5
If you intend this module to be compatible with earlier perl versions, please
specify a minimum perl version with the -b option.

Writing Foo-Bar/lib/Foo/Bar.pm
Writing Foo-Bar/Makefile.PL
Writing Foo-Bar/README
Writing Foo-Bar/t/Foo-Bar.t
Writing Foo-Bar/Changes
Writing Foo-Bar/MANIFEST

とりあえず、今後テストを増やす時にそなえて、

$ cd Foo-Bar/
$ mv t/Foo-Bar.t t/00_compile.t

とし、MANIFEST内の対応する記述を修正します。

あとは、こんな風に、

$ perl Makefile.PL PREFIX=~/local/perl
Checking if your kit is complete...
Looks good
WARNING: Setting ABSTRACT via file 'lib/Foo/Bar.pm' failed
 at /usr/lib/perl5/5.8.5/ExtUtils/MakeMaker.pm line 571
Writing Makefile for Foo::Bar
$ make
cp lib/Foo/Bar.pm blib/lib/Foo/Bar.pm
$ make test
PERL_DL_NONLAZY=1 /usr/bin/perl "-MExtUtils::Command::MM" "-e" "test_harness(0, 'blib/lib', 'blib/arch')" t/*.t
t/00_compile.t .. ok
All tests successful.
Files=1, Tests=1,  0 wallclock secs ( 0.03 usr  0.00 sys +  0.03 cusr  0.02 csys =  0.08 CPU)
Result: PASS

perl Makefile.PLして、makeして、pmを修正して、make testの繰り返しで単体テスト付きの開発プロセスが回ります。

PODをちゃんと書いてないので警告がでてますね。PODについてはまたの機会に書きます。

make時に、MANIFESTに書いてあるのに、実際にないファイルは警告がでますので、
案外それで間違いを気付いたりして重宝します。

ところで、perl Makefile.PLでは、PREFIXを指定していますが、自分が管理者じゃない場合に
make install時に、インストールする先を指定します。これがないと、/usr/lib/perl5とかに
作ったpm類をコピーしようとしますが、管理者権限がないと失敗します。
また、自分で作ったモジュールはperlの場所じゃなくてどこか別の場所で管理する場合なども
指定するとよいと思います。

私の場合は、

$ cat ~/bin/localmake
#!/bin/sh
perl Makefile.PL PREFIX=~/local/perl
make

として、localmake,make test,make installのような感じにしています。

まとめ

プロとしてのPerlプログラマが身につけておくべきことについて、
まずは開発プロセスをh2xsとmakeで構築することについて述べてみました。

これで、単体テスト付きの開発プロセスを手軽に導入することができます。

PODのことやテストの内容に関しても次以降に書く予定です。

「ブログチェックは仕事のうち」は「付き合いは仕事のうち」より理解されない

最近思うことですが、

「ブログチェックは仕事のうち」は「付き合いは仕事のうち」より理解されない。

ということです。
まあ、ブログチェックもほどほどにしましょう。

自分でもあんまり仕事上は重要でないと理解しているブログのチェックの合間には洗濯物干しの手伝いなどをすると吉です。
ママにっこりで、自分の内なる罪悪感も解消されます。

さくらのレンタルサーバ(スタンダード)を契約しました。

ログインシェルがcsh?っぽいので、慣れているbashにするのと、
vimが入っていないためvimをインストールしたのでメモしときます。

ログインシェルの変更

%which bash
/usr/local/bin/bash

というわけで、bashの場所がわかったので、

%chsh

で、最初のShell: を/usr/local/bin/bashに変更します。

確認のために再度ログインしたら、いつもの見慣れたbashのプロンプトになりました。

bashの設定

とりあえず、.bash_profileを作ります。
といっても、サブシェル起動時に読み込まれる.bashrcと同じにするため内容は

[ユーザ名@ホスト名 ~]$ cat .bash_profile
source .bashrc

さくらのデフォルトを引き継ぐように、.bashrcの内容は

[ユーザ名@ホスト名 ~]$ cat .bashrc
source .profile

PATH=$PATH:~/local/bin

PATHはvimのための布石です。

vimのインストール

先ほど設定したPATHにvimが入るように

[ユーザ名@ホスト名 ~]$ mkdir -p local/src
[ユーザ名@ホスト名 ~]$ cd local/src
[ユーザ名@ホスト名 ~/local/src]$ wget ftp://ftp.vim.org/vim/unix/vim-7.2.tar.bz2
[ユーザ名@ホスト名 ~/local/src]$ wget ftp://ftp.vim.org/pub/vim/extra/vim-7.2-extra.tar.gz
[ユーザ名@ホスト名 ~/local/src]$ wget ftp://ftp.vim.org/pub/vim/extra/vim-7.2-lang.tar.gz
[ユーザ名@ホスト名 ~/local/src]$ tar jxf vim-7.2.tar.bz2
[ユーザ名@ホスト名 ~/local/src]$ tar zxf vim-7.2-extra.tar.gz
[ユーザ名@ホスト名 ~/local/src]$ tar zxf vim-7.2-lang.tar.gz
[ユーザ名@ホスト名 ~/local/src/vim72]$ ./configure --prefix=$HOME/local
[ユーザ名@ホスト名 ~/local/src/vim72]$ make
[ユーザ名@ホスト名 ~/local/src/vim72]$ make install
[ユーザ名@ホスト名 ~/local/src/vim72]$ ls ~/local/bin
ex              rvim            vim             vimtutor
rview           view            vimdiff         xxd

うまくいったっぽいので、きれいにしておきます。(3GBしかないですから。。)

[ユーザ名@ホスト名 ~/local/src/vim72]$ make clean

vimの設定

後は、自分の.vimrcをホームディレクトリにアップして終了です。
私の場合は、directory-=.を入れているので、それ用に

[ユーザ名@ホスト名 ~]$ mkdir tmp

しました。

インストール直後のduで90Kだったのが、71Mになりました。

2009-07-02 追記

日本語環境のことをやっていないと思い、.bashrcに export LANG=ja_JP.UTF-8 を追記しました。

そしてvimを使ったら、ステータス行に文字化けが。。。

よく見返してみると、configure時に、--enable-multibyteがありませんでした。よって、

[ユーザ名@ホスト名 ~/local/src/vim72]$ ./configure --prefix=$HOME/local --enable-multibyte

でやり直して、再インストールしました。

そういえば、4月末からやっと仕事にありつけました。
12月の花子の出産以降久しぶりに継続的なお仕事になりそうです。
そこではPerlの案件ばかりなので、心機一転勉強しなおしながらやってます。
やっぱいいよPerl。何がいいのか言葉ではうまく言えませんが、すごく楽しいです。
また、PHPには戻りたくなくなってきました。
それとmixiの勉強会とEric Sinkの革新的ソフトウェア企業の作り方っていう本に影響されて
自分の製品を開発したくなりました。MTOSのプラグインにするつもりで、勉強中。