YapcAsia2007
[[PageOutline(2, 目次, inline)]]
Mark Json Dominus - Higher-order parsing techniques
Higher-Order Perl という本で有名な人。通称 mjd.
日本の Perl ギークは「マジデ」と呼ぶ。(こともある。)
プレゼンの内容は Higher-Order Perl にも書かれてるみたい。
高階関数やクロージャを使うと、構文解析プログラムがこんなにすっきり書けるよ!というお話。
このプレゼン自体では、高階関数やクロージャの説明がなかった。ので簡単に説明すると、クロージャとは、Perl で書くとこんな感じ。(言葉の定義は Wikipedia とか参照。たぶん、言葉の定義だけ見てもよくわからないと思う。)
#!perl
#!/usr/bin/perl
use strict;
use wanings;
sub calc {
my $op = shift;
return sub {
my ( $a, $b ) = @_;
return eval "$a $op $b";
};
# このリターンされている無名サブルーチンがクロージャ。
# サブルーチンの外で定義されている $op を内部で参照している
# ことに注目。この様に外部で定義された変数を内部に閉じ込める
# ので「クロージャ(Closure, 閉包)」と呼ばれる。
}
my $plus = calc('+');
print $plus->(3, 2); # 結果は 5
my $minus = calc('-');
print $minus->(3, 2); # 結果は 1
こんな感じで、加算する関数と減算する関数を、ひとつの関数定義から生成できる、という感じで、クロージャを使うと似たような関数の生成が楽になる。(クロージャの用法はこれ以外にもあるけど。)
また高階関数とは、「関数を引数にとる関数」のこと。例えばこんな感じ。
#!perl
#!/usr/bin/perl
use strict;
use warnings;
sub calc {
my $op = shift;
return sub {
my ( $a, $b ) = @_;
return eval "$a $op $b";
};
}
my $plus = calc('+');
my $minus = calc('-');
# ここまではクロージャの例と一緒
# 複数の関数の結果を掛け合わせる関数
# これが高階関数
# 引数だけでなく、結果も関数となっている(クロージャ)
sub multiply {
my @funcs = @_;
return sub {
my ( $a, $b ) = @_;
my $result = 1;
for ( @funcs ) {
$result *= $_->($a, $b);
}
return $result;
};
}
# 加算関数と減算関数を掛け合わせる関数を multiply で生成し、
# 引数に 5 と 3 を与える
multiply($plus, $minus)->(5, 3); # ( 5 + 3 ) * ( 5 - 3 ) が実行され結果は 16
高階関数とかクロージャとか知らない人は、これだけでお腹いっぱいになる気がする。
クロージャとか高階関数って、どんなものかは知っていても、使うことがあまりなかったり、どう使うのかがよく分からなかったりするが、このプレゼンでの構文解析プログラムがその回答のひとつ。
あとは細かい Perl コードの話になるので省略。クロージャ使って似たようなパーサコードの生成を簡略化し、連続した関数の実行を if + && でやっているところを、高階関数をつかうことによってまとめてすっきりさせる、というのがだいたいの流れ。
あと、「バックトラッキングも重要だけど、詳しくは本を読んで」とのこと。
Ingy からの「Wiki パーサにも応用できるか」との質問に「できる」と回答してた。自分も Trac の Wiki 記法パーサモジュールを CPAN にあげてるので、参考になりそう。特に、リストのパースは自分で書いた処理がいけてなくて、時々動きがおかしかったりするのだけど、 これを参考にすれば いい感じで書けそうだ。というわけで、Higher-Order Perl 買う。
Naoya Ito - Perl and UNIX Network Programming
Perl の「今風な」ネットワークプログラミングに関するお話。
Perl による UNIX ネットワークプログラミングの基礎
- BSD Socket API with C (not perl)
- Socket モジュール (C API に近い)
- IO::Socket モジュール (オブジェクト指向で書きやすい)
ブロッキング
- sysread でブロックが発生
- busy loop と blocking は別 (busy loop は CPU 時間を消費、blocking は消費しない)
- ブロックされているプロセスは TASK_UNITERRUPTIBLE になり、デバイスからの割り込み待ちとなる
並列処理
- プロセスフォーク
- スレッド
- シグナル I/O
- I/O 多重化
- 非同期 I/O
I/O 多重化
- ファイルディスクリプタの I/O イベントを監視
- fork/threads よりもリソース消費量が少ない
- select(2)/poll(2) を利用
select
- perl だと select() か IO::Select を利用
- FD_SETSIZE の制限がある
- 非効率 (FDs のカーネルへのコピー、全ての FDs をスキャン)
select(2)/poll(2) よりもモダンな API
- epoll (Linux 2.6)
- /dev/kqueue (BSD)
- devpoll (Solaris)
epoll(4)
- FDs の制限なし
-
O(1) スケーラビリティ
- FDs のコピーの必要なし
- イベントの発生した FDs のみリターンされる
epoll on perl
- Sys::Syscall
- IO::Epoll
今風の Perl ネットワークプログラミングライブラリ
-
POE
-
Event::Lib
-
Danga::Socket
-
Event
-
Stem
-
Coro
-
...
-
イベントベースで並列化
-
システムコールの抽象化
- select(2) / poll(2) / epoll / kqueue(2) / devpoll
POE
-
イベントドリブンな並列処理用フレームワーク
-
プログラミングを容易にしてくれるコンポーネントがたくさん
- PoCo::IRC
- PoCo::Client::HTTP
- PoCo::Server::HTTP
- PoCo::EasyDBI
- PoCo::Cron
- PoCo::Client::MSN
- PoCo::Client::Lingr
- ...
-
POE::Loop::Epoll
Event::Lib
- libevent のラッパー
-
libevent は
- イベントベースプログラミング
- システムコールの抽象化
- Event.pm に似てる
- シンプル
Danga::Socket
- Brad Fitzpatrick (イケメン) 作
- イベントドリブンプログラミングと epoll の抽象化
- Perlbal とか MogileFS とかで使われてる
まとめ
- ネットワークプログラミングには、OS、特にプロセススケジューリング, I/O, TCP/IP の実装に関する知識が必要
- コードをシンプルに保つために、モダンなライブラリを使おう
- perl にはいいライブラリがたくさんあるよ
Ben Trott - How we build Vox
APIs: Tools
-
カスタムライブラリを使う
- Net::Amazon や Net::Flickr はつかわない
- XML パーサがたくさんあって、それぞれ利用するパーサが異なる
- XML::LibXML のみを使う
APIs: Open Media Profile
- Open Search のメディアデータ版?
APIs: Outboud
- Atom Publishing Protocol
- すべての情報を Atom/RSS で
-
Cool URIs
- /library/posts/atom.xml
- /library/posts/2007/03/atom.xml
- /library/posts/2007/03/tags/yapc/atom.xml
Ajax
-
JSON でシリアライズ
- 軽量
- よく使われている
- Catalyst + JSON-RPC
- すべてが API
- 独自コア JS ライブラリ
Data::ObjectDriver
- MT や TypePad で使われている OR マッパー
Data::ObjectDriver: Caching
-
memcached のビルトインサポート
#!perl
Data::ObjectDriver::Driver::Cache::Memcached->new(
cache => Cache::Memcached->new({ servers => [ ... ] }),
fallback => Data::ObjectDriver::Driver::DBI->new(
dsn => 'dbi:SQLite:dbname=global.db',
),
);
Data::ObjectDriver: Partitioning
#!perl
Data::ObjectDriver::Driver::Cache::Cache->new(
cache => Cache::Memcached->new({ servers => [ ... ] }),
fallback => Data::ObjectDriver::Driver::SimplePartiotion->new(
using => 'Recipe',
),
);
JobQueueing
- 重い処理を Apache から切り離して実行
-
TheSchwartz
- 非同期、信頼性の高いジョブキュー
- N データベース
- ジョブハンドリングのためのワーカープール
Template Toolkit
- 重い
- キャッシュを有効活用
- バージョン化されたキャッシュ
Perlbal
- Perl 製負荷分散リバースプロキシ
- CSS, 画像, JavaScript など、スタティックファイルの配信もできる
- 複数の JS や CSS をひとまとめにして配信できる
- Last-Modified や If-Modified-Since もちゃんとハンドリングできる
Tomohiro Ikebe - Inside livedoor 2006 - 2007
-
Livedoor でも LiveDoor でもなく livedoor が正しい
Softwares
- FreeBSD or Linux
- Apache 2.0, 2.2 - Reverse Proxy
- Apache 1.3 - mod_perl
- MySQL 4.0, 5.0
- memcached
- Sledge
WEB+DB PRESS とかまるごと Perl とか見れば詳しく載ってる。
CVS から Subversion へ
- CVS ださい/飽き飽きしてきた(が、なんとかなる、意外といける)
- 「CVS は小学生まで」ということを事あるごとに言う人がいるので乗り換え
- mod_dav_svn
- HTTP Authentication
- mod_dav_svn + mod_auth_mysql + Catalyst
- Trac
Sledge
- MVC フレームワーク
- 2001年からある
- 安定してるけど古い
Sledge 2.0
- Rails, Catalyst いいよね
- なのでぱくる
- stash, Sledge::View, Helper, module name based dispatch など
- 10分でつくる Sledge アプリと言う名のタイピング自慢 by にぽたん
- Sledge 2.0 はムーブメント(なので完成すると思わないでほしい)
他の言語
- Perl 90%
- C - Apache モジュール
- Java - Lucene
Apache module
- ちょっぱや
- APR 便利(メモリ管理、文字列操作)
- mod_livedoor_sso.so
- mod_livedoor_page.so
mod_livedoor_page.so
- ClearSilver テンプレートエンジン
ClearSilver vs. Template Toolkit
- ClearSilver が圧倒的に速い
Catalyst
- カスタマサポートツールとかバックオフィスツール
Madeleine CMS
- Catalyst + DBIx::Class
- Radiant CMS っぽいもの
- Write your pages with TT syntax.
- Yahoo UI Library, FCKEditor
- Open Source!
クローラ
- Xango
- Parallel::ForkManaer
Next Stage
- No RDBMS
- 分散ファイルシステム
- ashiatod, ○○d (ちっちゃい仕事をするデーモンをいっぱいつくる)
- 文書のクラスタリング、カテゴライズ
Coming Soon
- 認証 API(ユーザハッシュ or ID ベースの認証)
- livedoor Reader 英語バージョン
- 新しいブログサービス