あと味

たくさん情報を食べて、たくさん発信すると、あとになって味わい深い。

PSGI + SeleniumでMTの管理画面のテストをする

MTの管理画面は、JavaScriptに依存した部分が結構多く、PhantomJS等のヘッドレスブラウザを使ったテストが必要になるケースがあります。

CasperJSや、Seleniumなど、いろいろなツールがありますが、MTの管理画面のロジックは、Perlで書かれているので、Perlで書けるのがベストです。Perlでデータの初期化とかしたいですからね。

Perlで書ける方法でツールを絞り込むと、現状では、Selenium::Remote::Driverを使うのが良い気がしています。

ということで、下記のようなテストを書いてみました。

テストの実行には、MTのGitHubリポジトリに含まれる、tディレクトリが必要です。あと、試す場合は環境変数MT_CONFIGを書き換えずに、MT::TestでDBを初期化すると、既存データが吹っ飛ぶので、テスト用の環境は別途用意した方が良いです。

Test::TCPで、GhostDriverと、MTのPSGIの管理画面を空いてるポートで起動して、Selenium::Remote::Driverを使って、管理画面を操作する感じです。

実際書いてみると、いろいろハマりどころがあった感じですが、ハマりどころを回避しつつテストを書くことになりそうです。

テストと同時にキャプチャを撮れるので、エビデンス対策も取れてよいですね。上記のコードではダッシュボードと、記事作成後の画面をキャプチャしていて、下記のような感じのキャプチャが撮れました。JavaScriptも処理されていて、ちゃんとした見た目になってます。

f:id:jdg:20140501090135p:plain

f:id:jdg:20140501090152p:plain

もう少し便利メソッドをカジュアルに使いたい場合は、Wight を使うのも良い気がします。

他言語でもSelenium使う機会があるかもしれないので、今後の学習コスト削減のために、今のところは単純なアダプタであるSelenium::Remote::Driverを使おうと思います。

ほなの。

Perlでメソッドチェーンのメソッドを動的に決定する

Perl でメソッドを呼び出す時、

$class->$method;

みたいな呼び出し方できるのは知ってたけど、

$class->${ \'method' }

みたいな感じで、文字列のスカラーリファレンスをデリファレンスすることでも同じことができることを知った。

これを用いることでメソッドチェーンのメソッドを動的に決定することができる。

上記のように pass とかいうメソッドを用意しておけば、不要なメソッドはスキップするということもできるので、そのチェインを実行するかどうかも動的に決定できる。

コードは結構キモい感じだけど、それなりに実用性はありそう。

サクッとPSGIなMTOSの開発環境を用意する方法

MTは5.2.2からPSGI対応したということで、今までPSGIアプリケーションをMojoliciousやMENTAで作ることもあった自分としては、かなり嬉しい出来事でした。

Mojoliciousなどは、開発用のPSGIサーバーも同梱されていて、ポータブルだし、サクッと開発環境を用意して、プログラム書き始めることができるのがとても良いですね。

どのCMSApacheの設定から始めて、DB作って、それらの開発環境を外に持っていく時も同じようなことをして云々かんぬんというのに辟易していました。Cartonなどを利用すれば、Perlの実行環境を除いて、アプリケーションディレクトリ配下にアプリケーションが動作するすべての条件を含めることができるのが快適で快適で。

これとなるべく近いことをMTOSでやってみようという試みです。基本的にPSGIで動かす話なので、CGIで動かす場合は、今までどおりメンドイですね。

MTOSを取得する

MTOSはGithubで公開されているので、とても助かります。

$ cd /path/to/yoursite
$ git clone https://github.com/movabletype/movabletype.git mt

これで取得完了です。特定のbranchや特定のtagのファイルが必要な場合は、以下のコマンドも適宜実行しましょう。

$ cd mt
$ git tag -l
$ git checkout -b mt5.2.3 origin/mt5.2.3

とか、

$ git branch -r
$ git checkout -b develop origin/develop

とか。

以降、すべての操作をmtディレクトリの中で行うので、cdコマンドは省略します。

最後にmakeします。

$ make me

シェバンを書き換える

すべての.cgiのシェバンが、/usr/bin/perlになってますが、自分の開発環境で、そのPerl使うことは皆無ですし、CPANモジュールもまったく追加してないので、シェバンはワンライナーで書き換えます。

$ find . -name '*.cgi' -or -name '*.t' -o -name '*.pl' -o -name '*.psgi' | xargs grep -lE '^#!/usr/bin/perl' | xargs perl -p -i -e 's|^#!/usr/bin/perl(\s*(?:-w)?)$|#!/usr/bin/env perl$1|'

DBを作成する

これもSQLiteでできればなー・・・。という感じ。他はすべてアプリケーションのディレクトリに閉じ込めることができますが、ここばかりはどうにもなりませんね。

MySQLの設定 : Movable Type 5 ドキュメント

この辺は、今後、コマンドラインスクリプトで自動化しようと思います。

ディレクトリの配置

こんな感じにするのが良いと思います。

www (プロジェクトのルート)
├─ mt (MTのCGIPath)
├─ mt-static (MTのStaticPath)
└─ public (公開領域)

以下、このディレクトリの配置を前提に、設定ファイルにパスを書いています。

mt-config.cgiを用意する

最小限のmt-config.cgiは以下のような感じになりました。

CGIPath /mt/
StaticWebPath /mt-static
StaticFilePath /path/to/mt-static
ObjectDriver DBI::mysql
Database database
DBUser dbuser
DBPassword dbpassword
DBHost localhost
DefaultLanguage ja

/mt/foo.cgiが、それぞれ別個のPSGIアプリケーションになります。MTの管理画面は、/mt/mt.cgiです。

app.psgiを用意する

mt.psgiというものがあるのですが、書き換えたいのと、plackupでファイル名指定するのが面倒なので、mtディレクトリ配下にapp.psgiを用意します。ちなみに、コレが今回の肝です。

use strict;
use warnings;
 
use lib qw(lib);
 
use MT::PSGI;
use Plack::Builder;
 
builder {
    enable 'DirIndex',
        dir_index => 'index.html';
    enable 'Static',
        path => qr{^/(?:(?!mt/|mt-static/))},
        root => '/path/to/public';
    MT::PSGI->new()->to_app;
};

Plackミドルウェアを2つ使っています。mt.psgiは個別のPSGIアプリケーションを包括した大きなPSGIアプリケーションになっていて、中でMT標準のアプリケーションやら、プラグインで利用するアプリケーションやらをPSGIアプリケーションにして、マウントしてみたいな処理をしています。

外から、mt.psgiを拡張しようとすると、今のところ、Plackミドルウェアしかないのかなーと思っています。

とは言え、既存のPlackミドルウェアの資産が活用できるのは魅力です。
もしかしたら、今後、MTのプラグインだけではなく、mt.psgi用のPlackミドルウェアもいろいろ出てくるのかもしれませんね。

静的ファイルを配信するためだけに、Apacheを設定するのは流石にだるいので、PSGIサーバーさん(plackup)に、そこんとこも頼むことにします。

静的コンテンツを配信するミドルウェアであるPlack::Middleware::Staticと、特定のファイル名をApacheのDirectoryIndexのように設定できるPlack::Middleware::DirIndexを利用しています。

Plack::Middleware::DirIndexの方は、Plack::Middleware::Staticの正規表現をもうちょっと書いたら不要かもしれません。もしくは、インラインでミドルウェアを書くとか。

ちなみに、Plack::Middlewara::DirIndexの存在は、Plackのgithub上にあったIssueで知りました。

MTOSの起動

plackup

以上!

デフォルトでは、ポートが5000番で起動するので、http://localhost:5000/mt/mt.cgiがMTの管理画面、http://localhost:5000/がサイトルートになります。

まとめ

以上で、割とポータブルで、サクッと用意できるMTOSの開発環境が用意できたと思います。用意が楽な上に、今までより速いです。

一応、公式では、plackupの制約上、PSGIサーバーはStarmanの利用が想定されていて、plackupはあくまで開発用と割り切って使いましょう。プラグイン入れた時とかアップグレード後とか何かと再起動必要だし。

初期状態では、CPANモジュールがいろいろ足らないと思いますが、この辺の依存関係を書いたMakefile.PLを用意して、Cartonで管理するのが良いと思います。

公開サーバーにMTを置かないという選択肢があるなら、これだけでも、高機能な静的HTML生成器になるし、汎用的なテキストファイル生成機になりますね。

Movable TypeのextlibディレクトリのCPANモジュールカタログ

Movable Type Advent Calender 2012の5日目です。

Movable Typeのプラグイン開発は、ダイナミック・パブリッシング対応のためにPHPを書くのを除いて、主にPerlのプログラムを書くことになります。

Perlのプログラムは、標準のモジュールだけで開発できることは少なく、様々なCPANモジュールを組み合わせて書いていくことが多いです。

プラグインの開発をする際、プラグインにCPANモジュールを同梱することもできますが、すでに同機能を実現できるモジュールが標準で用意されているのであれば、そちらをまずは使った方が、依存モジュール等でややこしくなくて済むので、まず、MT_HOME/extlibディレクトリの中にあるモジュールをいろいろと調べることがあります。

この機会に自分の備忘録も兼ねて、デフォルトのextlibディレクトリにある、CPANモジュールのカタログを作ってみました。

調査したバージョン

Movable Type 5.2(MTOS)

モジュールカタログ(アルファベット順)

以下、モジュールをアルファベット順に並べています。MT本体で利用されていない単なる依存モジュールかつ、個人的に使わなさそうなものは独断と偏見で省く可能性があります。ご了承下さい。

A

Algorithm::Diff
2つのファイル、リストの差違を求める関数を含んだモジュール。

MT本体では利用されていませんが、HTML::Diffの依存モジュールです。他に使えることもありそう。

Apache::*
mod_perl絡み。

MT5以降では、mod_perlをサポートしていないようなので、今後使わないのかもしれない。プラグイン開発には必要ないのかな。

Archive::Extract
圧縮ファイルの展開をする時に使うモジュール。

MT本体では使われていないようですが、Archive::ZipやArchive::ExtractのPODを見ると、解凍だけなら、こちらを使った方がメモリ消費量を節約できるっぽいです。(unzip等のコマンドが利用できる前提)

Attribute::Params::Validate
Params::Validateを属性を使って利用するモジュール。

特に使われているところは無さそうだけど。

AutoLoader.pm
AUTOLOADで呼ばれるメソッドをファイルに書きだしておけるモジュール。

Image::Sizeで使われてる。

C

CGI::*
言わずと知れたモジュールですね。

MT::Appで使われています。直接使うことは無さそう。

Cache::*
キャッシュのインターフェイス。

Data::ObjectDriverのサンプル・コードに出てくる程度。標準のextlibには入っていない、推奨モジュールのCache::Fileとか、Cache::Memcachedの方が有用そう。

Class::Accessor::*
アクセサの定義を簡単にするためのモジュール。

MT内でも使われているし、クラス作る時に有用。

Class::Data::Inheritable
アクセサの定義を簡単にするためのモジュール。Class::Accessorとの違いは、インスタンス変数へのアクセサか、クラス変数へのアクセサかです。

Data::ObjectDriver::Driver::BaseCacheでは、両方をClass::Accessor::FastとClass::Data::Inheritableとを使い分けています。

Class::Inspector
クラスについていろいろ検査するモジュール。

SOAP::Liteの依存モジュールのようです。とあるクラスをロード済みかどうか調べるのに使ってました。

Class::ErrorHandler
クラスのエラーメソッドを簡単に定義するためのモジュール。

URL::Fetchの依存モジュールのようです。

Class::Trigger
クラスにトリガーを設定するためのモジュール。

MTのフック・コールバックはこの仕組で実装してるっぽい。

Crypt::DH
DH法のためのモジュール。

Net::OpenID::Association等の依存モジュール。鍵作るのに必要みたい。

D

Data::ObjectDriver::*

ORマッパー。

MTで独自オブジェクト作る時は間接的にお世話になる。

F

File::Copy::Recursive

再帰的にファイルのコピーや移動をするためのモジュール。

MTでは、MT::CMS::Themeでエクスポートする時に使われている。

File::Listing

ファイルやディレクトリの一覧を出したい時などに使うモジュール。

LWP::Protocol::FTPで、ファイルの一覧をHTMLで返す時にファイル一覧ページを作るために使われている。

File::Tmp

TempファイルやTempディレクトリを作りたい時に使うモジュール。

MTでは、ファイルのアップロードで重複したファイル名の場合、上書きする時などに使われる。

H

HTML::Diff

二つのHTMLのdiffを取るモジュール。

MTでは、MT::Revisableで使われてますね。リビジョンの機能を使う時にお世話になってるってことです。

HTML::Form
HTMLのform要素をオブジェクトとしてパースするモジュール。

どこでも使われていなっぽいけど、LWP::UserAgentなんかと組み合わせて使うみたい。

HTML::Template
HTMLのテンプレートエンジン。

かつてのバージョンでは、MTの管理画面はHTML::Templateで書かれていたようで、その名残りだと思われます。MT::Builderには、HTML::Template形式のテンプレートをMTタグに変換するコードが入ってました。

H

HTTP::*
HTTPプロトコル周りのインターフェイス。

依存モジュールが大半で、MTでは、HTTP::RequestとHTTP::Response、HTTP::Dateあたりが実際に使われています。

Heap::Fibonacci
フィボナッチヒープを取り扱うモジュール。

MT内では使われていなくて、Cache::Memoryの依存モジュール。

フィボナッチヒープ自体、何が良いのか一度作ってみないと理解不能な感じなので、よくわかりません。

I

I18N::LangTags::*
RFC3066形式の言語タグを取り扱う関数をエクスポートするモジュール。

Locale::Maketextの依存モジュールで、MT::L10Nでも使われてます。言語タグから言語名を取得するのに使ってるだけかな。

IO::Scalar
スカラ変数をファイルハンドルっぽく扱うためのモジュール。

MTでも依存モジュールでも使ってなさそう。

IO::WrapTie
IO::Handleインターフェイスでtieされたオブジェクトを扱うためのモジュール。

IO:Scalarの依存モジュール。

IPC::Cmd
外部コマンドをPerlから簡単に実行するためのモジュール。

MTでは直接利用していない。Archive::Extractの依存モジュール。tarコマンドやらzipコマンドやらを使う時に利用されている。

Image::Size
画像のサイズを取得するためのモジュール。

MT内でも、MT::Imageや、MT::Asset::Image等、画像サイズの取得が必要な場面で利用されている。

J

JSON::*
PerlでJSONを取り扱うためのモジュール。

MT内でもJSONを取り扱う箇所でいろいろ使われています。

L

LWP::*
PerlのWWWクライアントツール群。

MTでは、主に、LWP::UserAgentが外部サイトへのアクセス等で背面化でいろいろ働いてます。MT->new_uaで、MT用にカスタマイズされたUserAgentが作れるようになっています。

Locale::Maketext
ローカライゼーションのためのフレームワーク

MTのローカライゼーションの基盤です。プラグイン開発で使う、translate関数の元です。

Lucene::QueryParser
全文検索ソフトLuceneののクエリパーサ。

MTでは、MT::App::Search等で使っていて、検索クエリの解析に使ってるみたい。

M

MIME::Charset
MIMEのためのCharset情報を扱うモジュール。

MTでは直接使っていなくて、MIME::EncWordsの依存モジュール。

MIME::EncWords
RFC2047形式でエンコードされた文字を扱うためのモジュール。

MT::Mailでメールのヘッダをエンコードするのに使われている。

Math::BigInt
BigIntを扱うためのモジュール。

MT::Utilのdsa_verifyで、Crypt::DSAがない時に、これを使ってなんとかしている。

Module::Load
モジュールローダー。

Module::Load::Conditonalの依存モジュール。

Module::Load::Conditional
モジュールの情報によってロードするモジュールローダー。

MT内では使われていませんが、Archive::ExtractやIPC::Cmdの依存モジュールで、can_loadメソッドが使われています。

N

Net::HTTP
HTTPクライアント。

MT内では使われていません。LWP::Protocol::httpやNet::HTTPSの依存モジュール。

Net::HTTPS
HTTPSクライアント。

Net::HTTPと同じく、LWP::Protocol::httpsの依存モジュール。

Net::OAuth
PerlでOAuthを扱うためのモジュール。

もしかしたらコマーシャルパックでは利用するのかもしれませんが、MTOSでは利用してなさそう。

Net::OpenID::*
PerlOpenIDを扱うためのモジュール。

MTでは、MT::Auth::OpenIDで使われています。コメント投稿時にOpenID使う時とか。

P

Parms::Check
関数の引数をチェックするモジュール。

MT内では使われていません。Archive::Extractや、Module::Load::Conditional等で引数チェックに使われています。

Params::Validate
関数の引数をバリデートするためのモジュール。

MT内でも、何かの依存モジュールでもなさそう。

S

SOAP::*
SOAP関連のモジュール群。

MTでは、MT::XMLRPCServer等で使われている。

T

TheSchwartz::*
ジョブキューシステムTheSchwartz関連モジュール。

SixApart製ということもあり、MTのジョブキューシステムはこれで管理されている。

U

UDDI::Lite
UDDIクライアント。

MT内で使われてなさそう。

UNIVERSAL::require
モジュールローダーのひとつ。

Net::OAuthで使われている。

URI::*
URIPerlのインターフェイス。

MT内では、MT::App::Wizard、MT::AtomServer等、URIを分解する時等に利用されている。

W

WWW::RobotRules

MT内では直接使われてません。LWP::RobotUAの依存モジュール。

X

XML::Atom
ATOMのインターフェイス。

MTでも、MT::AtomやMT::AtomServer等、ATOM関連で使われている。

XMl::Elemental
XMLPerlオブジェクトにパースするモジュール。

XMl::Parser::Style::Elementalの依存モジュール。1

XML::Parser::Lite
正規表現ベースのXMLパーサ。

特に使われていない。

XML::NamespaceSupport
XMLのnamespaceのインターフェイス。

XML::SAXやXML::Simpleの依存モジュール。

XML::SAX
SAXパーサ。

MT::Utilで使われていて、MT::BackupRestoreに必要なモジュールになるので、ブログのバックアップと復元機能が使えなくなる。

XML::Simple
簡単に使えるXMLインターフェイス。

MT内では直接使われてないけど、XML扱う時には使えそう。

XML::XPath
XPathに基づくXMLパーサ。

MT内では、MT::AtomServerとMT::Auth::OpenIDで使われている。

XMLRPC::Lite
XMLRPCのPerl実装。

MT内では直接使われていませんが、XMLRPC::Transport::*の依存モジュール。

XMLRPC::Transport::*
XMLRPC::Liteの様々なプロトコルの実装。

mt-xmlrpc.cgiで、XMLRPC::Transport::HTTPが使われている。

Y

YAML::Tiny

YAMLファイルを読んだり書いたりするモジュール。

MTでは、MT::Util::YAML::Tinyという名で再定義されている。

V

version::*

バージョンオブジェクトを扱うためのモジュール。

まとめ

思ったより、必要最小限のモジュールしか使ってないなという印象がありました。やはりいろんな環境で動かそうと思うと、依存多すぎてもいけないってのがあるのかもしれませんね。extlib配下のモジュールのものでも、Perlのバージョンによっては標準モジュールになっているものもたくさんあります。

toolsの中に突如Web::Scraper依存のコードがあったり、コード書く人によって、違うのかもしれませんが。

どこで使われているかよくわからないものもありましたが、今回調べたバージョンで使われていなかったり、MTOSでは使われていないものもあったのかもしれません。

Tips

特定のモジュールが特定のPerlのバージョンの標準モジュールかどうかを調べるには、Module::CoreListが便利です。corelistというコマンドがインストールされるので、それを使えば標準モジュールを調べられます。

$ cpanm install Module::Corelist
$ corelist --help
$ corelist -a Module::Load

また、依存モジュールも含めてローカル領域にCPANモジュールをインストールするには、cpanmコマンドの方が楽でしょう。XS依存の部分はサーバーに単純に上げても使えませんが、*::PPとか書いてあるモジュール探すとか、metacpanでpure perlと検索して探して解決するとかで対処する感じですね。

$ cpanm -h
$ cpanm -L ./extlib Plack

cpanmのインストール等、Perlの環境構築については、あと味の[Perlの環境構築 - あと味などを参考にしていただければと思います。

最後に

来年はMovable Typeに本気で取り組みます。

Perlのリストのおもしろいところ

PerlのリストはPerlらしいというか、結構おもしろいなーと思うことがあります。

Perlのリストの面白いところを紹介してみます。

cons, append

Perlでconsとかappendするいい方法何かなーとか考えてた時に、リストの標準機能でできることに気づきました。

my @one_to_three  = (1, 2, 3);

# cons
my @zero_to_three = (0, @one_to_three);

# append
my @one_to_four = (@one_to_three, 4);

concat

同じような方法でconcat相当もできます。

my @one_to_three  = (1, 2, 3);
my @four_five_six = (4, 5, 6);

# concat
my @one_to_six = (@one_to_three, @four_five_six);

ハッシュ版cons, append, concat

Perlでハッシュを定義する時は、以下のように定義します。

my %foo_bar = (foo => 1, bar => 2);

これはいろんな書籍に書いてあることですが、以下の別記法です。

my %foo_bar = ('foo', 1, 'bar', 2);

ハッシュはkeyとvalueが対になったハッシュをリストコンテキストで評価すれば、ハッシュになるわけですね。

この特徴を利用すれば、ハッシュ版のcons, append, concatも可能になります。

my %foo_bar = (foo => 1, bar => 2);
my %baz_qux = (baz => 3, qux => 4);

# ハッシュ版cons
my %hoge_foo_bar = ('hoge' => 0, %foo_bar);

# ハッシュ版append
my %foo_bar_hoge = (%foo_bar, hoge => 3);

# ハッシュ版concat
my %foo_bar_baz_qux = (%foo_bar, %baz_qux);

面白いですね。

car(head), cdr(tail)

関数型言語でよくあるcar(head), cdr(tail)などもリストの標準の機能でOKです。これくらいのことをするのに、イチイチ関数なんていらんかったんです。

my ($car, @cdr) = (1, 2, 3, 4);

多値っぽいもの

多値っぽいものもできます。

my $zero = 0;
my $one  = 1;
my $two  = 2;

# リストの各要素に10足したリストを返す関数
sub map_add_10 {
  map { $_ + 10 } @_;
}

my ($ten, $eleven, $twelve) = map_add_10($zero, $one, $two);

便利ですね。

分配束縛っぽいもの

引数を分解するのも簡単です。超単純なheadとtailを関数にしてみましょう。(先ほどいらんかったんですって言ったとこですが...)

sub head {
  my ($x, @xs) = @_;
  $x;
}

sub tail {
  my ($x, @xs) = @_;
  @xs;
}

my $head = head(1, 2, 3);
my @tail = tail(1, 2, 3);

補足

面白いんですけど、リストは1次元しか表現できないので、2次元以上はこのワザは使えません。

ちなみに最近まで、同一視していたんですけど、配列とリストはPerlでは別物という扱いだそうです。

参考: リストと配列(Array)はPerlでは別物 - Togetter

まとめ

Perlのリストおもしろいですね。*1

*1:ただ、Perl関数プログラミングするのは、個人的には微妙な感じしてます

MovableTypeのモジュールのPODのViewerプラグイン作った

MovableTypeを触っていると、MTのモジュールのPODを見る機会が多くなります。MTタグの使い方とかも該当モジュールのPOD見れば解決することもあるので、とりあえずアイデアレベルですが、昨日作ってみたのでエントリー起こしました。

MTPodViewerという名前を付けました。

20121004112532

デモサイト

MTPodViewer

インストール

リポジトリにあるplugins/MTPodViewerをサイトのpluginsにコピーします。加えて、リポジトリにあるmt-static/plugins/MTPodViewermt-static/pluginsにコピーします。

依存モジュールはextlibに同梱したつもりですが、動かなかったらごめんなさい。cpanコマンドかcpanmコマンドでインストールしてください。依存モジュールは、plugins/MTPodViewer/Makefile.PLに書いてあります。

プラグイン設定

システムのプラグインに進むと1箇所だけ設定があります。

ログイン必須にするかしないかの選択です。Yesならログイン必須、Noならログイン不要です。

検索方法

たとえば、MTのディレクトリで、perldocする場合、以下のような感じになると思います。

$ perldoc lib/MT/App.pm

MTPodViewerでは、以下の様なキーワードで検索することになります。

app

MT::Template::Tags::Entryを検索したい場合は、

template-tags-entry

と検索します。

MTというプレフィクスは省略して、「/」や「::」の区切り文字を「-」にして、全部小文字にしているということです。

bootstrapのtypeaheadがある程度面倒見てくれるので、これで充分な気がしてます。

感想

最初はCSSとか自分で書いてたんですけど、途中からbootstrapに変更しました。bootstrap-typeaheadのスタイル作るの面倒だったので...。というか基本的にbootstrapは何かと楽でマジ助かります。

見出しのフォントはHelvetica、本文のフォントはGoogle Web Fontsにある、OpenSansにしました。すごく読みやすいですね、このフォント。

速度的にはちょっと微妙なので、モジュール一覧をキャッシュしておくなりした方がいいと思いますが、また気が向いたら対応します。

リンクの部分とかは、Pod::Simple::XHTMLの吐き出すソースをちょっとカスタマイズしたらうまくできるのかもしれませんが、ページ内リンクと別モジュールへのリンクがうまく場合分けできなさそうなので、リンクをすべて外すって対応を取っています。

MTアプリケーションはMTをWAFと思えば、普通に使えますね。クライアントワークだったら、依存モジュールの解決もそんなに面倒じゃないですし、最近は、MTアプリケーション作る機会もあって、いろんなCPANモジュールと組み合わせて使ってます。

あと、英語のドキュメント書けない。深刻。

kanazawa.rbで「Mojoliciousと愉快なPerl」という話をしてきました

つい先程の話。kanazawa.rbで「Mojoliciousと愉快なPerl」という話をしてきました。

Perlの記事を書いたことはあるけど、Perlについての発表をするのは初めてだったので、いつも以上に緊張した感じです。というか、ようやくプログラムの話ができるようになったという感じでしょうか。

スライド

スライドは以下に置いておきました。

話の内容

スライドにはキーワードだけ書いて、口頭での説明とデモがメインだったので、スライドだけ読んでもちょっと物足りないかもしれません。

発表でも話しましたが、かつてはRubyPerlから学ぶことが多かったけれど、今はPerlRubyから学ぶことが多いです。

Rubyの勉強会に参加するのも初めてでしたが、多分、Perlの人がRubyの勉強会に参加するのは、少し先の未来を覗き見することにもなるのかなと思います。

今回はSinatra vs Mojolicious vs Expressみたいな構図でしたが、それぞれパクリ愛に溢れていて、どれも素晴らしいものだと思いました。

ですが、発表の準備をするにあたり、Mojoliciousをいろいろ調べ直してみると、やっぱりMojoliciousが好きです。ひいきなしで、自分はSinatraよりも、Expressよりも、Mojoliciousが好きだなぁと。

Mojoliciousは、標準モジュール以外、すべて自前で用意しているし、どのCPANモジュールを使えばいいかわからないという人でも、とりあえず、Mojoliciousの用意しているモジュールやツールを使えば、Perlで簡単なWebアプリケーションを書くことができるでしょう。

今回の発表では、デモも交えて説明したのですが、Perl使うならperldocをたくさん使いましょうねっていう話をしました。

Rubyのドキュメントの文化とかはよく知りませんが、Perlはドキュメントがちゃんと整っているし、ちゃんと書かないといけない印象で、しかもperldocってツールが最高に使いやすいです。

PODという発明、良いプログラマは良い物書きでもあるという教えが、この文化を生んだのかなと思います。

まとめと反省

Rubyの勉強会に参加することで、Rubyの人になる可能性もありますが、もはや、Perlのキモかわいさに慣れてしまって、なかなか難しいような気もしています。*1

去年のYAPC::Asia TOKYO2011に参加して、感想記事を書いた中で、来年のYAPC::Asiaまでに、CPAN Authorになりたいとか、次回のYAPCではLTに出たいとか書いていましたが、結局この目標は未達になってしまいました。。。*2

自分を慰めるとすれば、Perlの勉強会ではないにせよ、Perlの発表をすることができたのと、Perlでツールを作って公開するということはできたという点でギリギリ赤点でしょうか。もっと精進します。

最後に

次回はkanazawa.rbの本編?である、beer会にも参加したいです。

kanazawa.rbの皆さん、今日はありがとうございました。

@wtnabeさん、ご招待ありがとうございました。

*1:個人的には、Rubyに転向するより、Clojureに転向する可能性の方が高い

*2:YAPC::Asia 2012に参加することすらできずorz...