2007年4月アーカイブ

Class::C3::XS vs SUPER




daisuke@beefcake next$ perl C3_SUPER.pl
Rate with_c3 with_super
with_c3 71942/s -- -45%
with_super 131579/s 83% --
daisuke@beefcake next$

YAPCで発表したベンチマーク内容をClass::C3::XSを使って動かしてみたら2倍近く速くなった模様。


追記:MacBookで再インストールする時についでに昨日(5/1)出てた最新版でもう一回やってみた



daisuke@beefcake next$ perl C3_SUPER.pl
Rate with_c3 with_super
with_c3 62893/s -- -79%
with_super 294118/s 368% --
daisuke@beefcake next$ perl C3_SUPER.pl
Rate with_c3 with_super
with_c3 192308/s -- -33%
with_super 285714/s 49% --
daisuke@beefcake next$

いやぁ。すごいねぇ。


MacBook 来る



はえええええええええええええええええええ。はえええええええ。はええええええええ!


ジーザス。速い。PowerBookが古代の遺物に見える。


いんでっくす



Mさん、ありがとうです。



http://lists.sourceforge.jp/mailman/archives/ludia-users/2007-April/000040.html



なんてタイムリー。


AI::Categorizerで日本語



AI::Categorizerで日本語を読み込んでみたら全然動かなかったので30分Hack。以下をAI::Categorizer::Documentが読み込まれた後に読み込むと一応動く。30分hackなのであまり信用しないように。



package AI::Categorizer::Document;
use strict;
use warnings;
use Text::MeCab;

sub tokenize_ascii {
my $self = shift;
my @tokens;
while ($_[0] =~ /([-\w]+)/g) {
my $word = lc $1;
next unless $word =~ /[a-z]/;
$word =~ s/^[^a-z]+//; # Trim leading non-alpha characters (helps with ordinals)
push @tokens, $word;
}
return \@tokens;
}

sub tokenize
{
my $self = shift;
if ($_[0] =~ /[\P{ASCII}]/) {
my @ret;
my $mecab = Text::MeCab->new();
for(my $node = $mecab->parse($_[0]); $node; $node = $node->next) {
push @ret, $node->surface;
}
return \@ret;
} else {
return $self->tokenize_ascii(@_);
}
}

1;

つきまとい



知り合いのサイトを見てて、いちいち内容に関係ないコメントがつくのを見てて正直気持ち悪い。つきまといはこわいぞぉ。


昨日の飯。



QN.N。朝:無し。昼:魚力のサバ味噌定食。おやつ:シフォンケーキ。夜:和布蕪と刺身にサントリースーパーブルーx1


魚力は実は結構久しぶり・・・


FormFu Model



下のエントリのCatalyst Modelでホゲホゲしてたら、HTML::FormFuの生成時間が気になってきた。レンダリングと同じくらい時間がかかりやがるので、これをキャッシュしたらいいんじゃね?と



my $form = $cache->get($form_file);
if (! $form) {
$form = HTML::FormFu->new( ... args ... ); # <- ここはちょっと注意必要
$form->populate( get_config($form_file);
$cache->set($form_file, $form);
}
$form->process( $c->request );
return $form;

こうすると同じHTML::FormFuオブジェクトでprocessをリクエスト毎に呼んで、効率的。生成時間は俺の開発サーバーで約4分の1。Micro optimizationかもしれんけど、ついでだったので色々変更してみた。


これが落ち着いたら、HTML::FormFuのMLでCatalyst::Model::FormFuを本格的に提案してみようっと。


インデックス破壊しまSHOW



あ、ちなみに昨日も今日もLudiaのインデックスがぶっ壊れました。今の段階では正直意味不明。デバッグもできん・・・


CatalystのModel



皆CatalystのModelってどう使ってるんだろう?最近今まで結構Controllerに入れてたロジックをModelに移行しつつあるんだけど、Modelって



$c->model('Hoge')->some_method(@args);



$c->forward('Model::Hoge', 'some_method', \@args);

と二つ呼び方があるじゃないですか。ずっと前者を使ってたんだけど、$c->forward()の使い方がようやくわかってきたので全部$c->forward('Model::Hoge')にしようかと思ってコード書いてみたら、$c->forward()の時だと引数に$cが入ってきて、いままで動いてたコードがいきなりぶっ壊れたりするわけですよ。


これってただ好みの問題かな。引数が変わってくるのめちゃくちゃむかつくんだけどなぁ・・・ちなみにforward()使おうと思った理由は



.----------------------------------------------------------------+-----------.
| Action | Time |
+----------------------------------------------------------------+-----------+
| /admin/area/begin | 0.032550s |
| /admin/area/load_area | 0.104095s |
| -> Hoge::Model::Area->find | 0.006322s |
| -> /admin/area/not_found | 0.000128s |
| /admin/area/end | 0.001169s |
| -> /admin/area/render | 0.000317s |
'----------------------------------------------------------------+-----------'

こういうのが見れるから。Chainedディスパッチャーとforwardをうまく使うとControllerのデバッグがすげぇ楽なのでModelでも使いたいんだけど・・・


昨日のご飯



朝:VIRONのパテ・ド・カンパーニュのサンドイッチ、昼:ねばたまうどん(中)、夜:塩ラーメン(ただし6割サイズの小)。お酒。


Elebitsストーリーモードクリア




エレビッツ

エレビッツ





すこーしずつ進めていたElebits、やっとストーリーモードをクリアしました。ストーリーモードをクリアすると「称号」が与えられるのですが、俺の場合は「破壊王」でした。どこのプロレスラーやねん。


POE



最初、なんでデコードとパフォーマンスが関係あるねん、とすごい考え込んでしまったが、俺らへのリンクは話の枕だったのね。おれがDISられたのかと思って憤慨したエントリ書くところだった。



http://blog.livedoor.jp/dankogai/archives/50816853.html



POEは確かにLWP::UserAgentに比べたら明らかにメモリ食います。1リクエストを発行するだけのためにPOEを立ち上げるためのプログラミングと時間/リソースのオーバーヘッドを考えると単純なGETを比較的遅めの間隔で行うのにはあまりおすすめできません。


POEやDanga::Socketのような非同期なフレームワークを使い始める真のメリットは多分1)半永久的に2)大量のURLを3)同時に 処理しつづける、という条件が揃ってる時だと思います。この点、POEとかは単純な"scraper"にはそれほど向いてない。あちこちのURLを取りに行く"crawler"ならいける。


あ、ちなみにGunghoはKeepAliveを効率よく使います。まぁPOEがkeepaliveに対応してるからなんだけど。



my $keepalive = POE::Component::Client::Keepalive->new(%$keepalive_config);
...
POE::Component::Client::HTTP->spawn(
Agent => "Gungho/$Gungho::VERSION",
%$client_config,
Alias => &UserAgentAlias,
ConnectionManager => $keepalive,
);

キャッシュカード紛失



なんか知らんけど昨日帰り際にふと気づいたらキャッシュカードがないでやんの。ということで今日は朝から銀行に行った。通帳記入を見る限り別に誰かに使われた形跡もないので、多分ATMに食われたか、俺の部屋の片隅の目に届かないところで眠っているんだろう。ちっ。


ところでカードを再発行してもらおうと思ったのに印鑑を持ち歩く習慣がないため、今日はできず・・・明日にもちこし。


昨日の飯



朝:ご飯、納豆、和布蕪。昼:姫竹蕎麦。夜:ビール、シェリー、カルバドスとアサリのオイル煮と小さめの黒パン


今日は朝飯食ってる暇がないな・・・ってことで行ってきます。


Ludia



SennaのPostgreSQL組み込み用ライブラリのLudia。こいつ、かなり速いし好きなんだけどひとつ問題が。毎日更新のある某DBにこれを突っ込んでおいたところ、毎日インデックスがぶっ壊れる。例えばほんの10分前まで動いていた、1個だけエントリーを抽出できてたSELECT文が急になにも返さなくなる。すると全部の全文検索を含むSELECT文が動かなくなるのです。今はまぁ一般公開してないからほぼ毎日のようにpsql -f rebuild_index.sqlってのを走らせてるのだけれども、常駐しているWebアプリがキャッシュされているステートメントハンドルを持っている場合は、同じインデックスを使ったクエリを発行しようとしてCan't locate relation with OID XXXXとか言われてしまうのでそのプロセスも止めないといけない。DBが落ちる訳ではないので微妙なんだよなぁ。


さらばApache



tracをちゃんと動かそうと思って色々やった結果、認証をちゃんと動かすためには今までのサーバー構成では駄目だと分かってApacheとおさらばする事にしました。今までは何個かレガシーなmod_proxy + mod_perlなアプリケーションが有ったのだけれども、Catalystベースの開発に移行してからはFastCGIが気持ちよくなってしまってめっきりmod_perlのアプリがなくなって行ったのです。で、そんなこんなしてる間にtracの件がでてきたのでもうApacheいいや、と。


というわけで移行。とりあえずまだ使ってみた事なかったから、というだけの理由でApache2.2を入れて(ここらへんが我ながら無駄)、lighttpdで作業している間に「ただいまメンテナンス中」を表示しておいてもらって、その間にlighttpdをポート9000で動かしつつ動作確認。最初は全然なんだかわからんかったけど、とにかくうごくようになったところで問題勃発。FastCGIとベーシック認証を一緒に動かすと止まる。なんじゃこりゃ。


もう書き方が悪いのかと思ってこれで2時間はまった。ところが正しい答えは単純:



server.modules = (
mod_fastcgi
mod_auth
)

は駄目で、



server.modules = (
mod_auth
mod_fastcgi
)

にすればいいだけの事。あとはちょこちょこやったら動いた。あー、疲れた。


追記:SVNだけはApache必要だったーーーーー。2.2でmod_dav_svnをバックエンドにして、lighttpdをフロントにしてみたよ。


Gungho vs PoCo::Clieht::HTTP



おお、毎度ありがとうございます。



http://labs.cybozu.co.jp/blog/kazuho/archives/2007/04/poco_patch.php



Devel::StackTrace をprereqに足したくないので、以下のようにしてとりこませてもらいます!



use constant SKIP_DECODE_CONTENT
BEGIN
{
if (SKIP_DECODE_CONTENT) {
eval <<' EOCODE';
no warnings 'redefine';
sub HTTP::Response::decoded_content {
my ($self, %opt) = @_;
my $caller = (caller(2))[3];
if ($caller eq 'POE::Component::Client::HTTP::Request::return_response') {
$opt{charset} = 'none';
}
$self->SUPER::decoded_content(%opt);
}
EOCODE
}
}

rev 63でいただきました。


Gungho Architecture



前回書いた、Gunghoのアーキテクチャの変更について。



http://d.hatena.ne.jp/lestrrat/20070421#1177116589



Gungho->newは全面廃止、いきなりGungho->run($config)とかでオッケーにした。Componentはこれ以降Gungho本体がオブジェクトではなく、ただのクラスであることを分かりつつコードを書く必要がある、ということにします。


rev 64で変更済み。


おつまみ本




おつまみ―お酒に合う料理478品

おつまみ―お酒に合う料理478品





先週末買ったので時々眺めてます。


PowerBookがピンチ



このところなんか調子が悪かったのですが、昨日はセカンドモニターにつなげているDVIポートが動かなくなったりしてついに新しいのを購入するか、とか検討。夜になっていよいよ変な音はするし、家に帰ったらすでに3回フリーズしてるし・・・


というわけでMacBookの黒いの買いました。このマックが死ぬ前に届いてくれるだろうか。


Catalyst->forward()



Catalystのforward()の挙動でforward($class, $action)とforward($path)の違いがよくわかってなかった。今度からちゃんと使う。もっと細かい違いがあるのかもしれないけど、とりあえず普通使いたいのは$pathだ。Actionがちゃんと付随して動作する。forward($class, $action)だと、ただcontextを渡しただけで$class->$action()と変わらない。


たまにはこうい朝食も作ります



知り合いから日向夏をもらったので、それと近所の濱田屋のパンでスクランブルエッグ。付け合わせは茄子、椎茸、タマネギをトマトソースで炒めたもの。濱田屋の食パンは初めてなのだけど、予想以上にうまくて感激。


レイトン教授と不思議な町




レイトン教授と不思議な町(特典無し)

レイトン教授と不思議な町(特典無し)





完クリしますた。ごめん、本当は最後の問題は夜中にやってて集中力なかったからズルした。


Gungho Components




http://d.hatena.ne.jp/kdaiba/20070419



Gunghoのコンポーネントはオブジェクト作成時に設定されます。なので自分でinject_baseする必要はないのです。



---
components:
- Throttle::Simple

これか、これと同等の事をGungho設定時に渡すだけでOK。んで、書きながら思ったんだけどここの設計、ちょっと考え直さなくてはいけないことに気づいた。componentsはCatalystを参考に作ったのだけど、実装としてはGunghoのベースクラスを変更するって事なので、コンポーネントの変更はグローバルに適用されるのだ。でもGungho->newってしてるってことはこれってインスタンス毎の設定してるような印象を与えるし・・・


ってことで、Gungho->newはちょっとやめようかと。Gungho->setup; Gungho->runのほうが実装的には正しい。インスタンス毎に設定を変えられるようにしてもいいんだけど、どうせ1度に複数インスタンスを動かす事はありえないのでこれでよいような気がするな。で、newはsetup()へのエイリアスにする、と。


コメント求む。



use Gungho;
Gungho->setup('config.yml');
Gungho->run;

  use Gungho::Inline;
  Gungho::Inline->setup({
     provider => sub { ... },
     handler  => sub { ... }
  });
  Gungho::Inline->run;

もしくは



use Gungho::Inline;
Gungho::Inline->run({
provider => sub { ... },
handler => sub { ... }
});

で済ませるか。


一番時間を費やしている事



この前最近の自分の生活で一番時間を費やしている事は何かと話していたら、どう考えても一位「仕事」、二位は「今日の献立を考えている」だ、という結論に達した。その話をしている時にもやはり「卵があるからスクランブルエッグ・・・それに水菜のサラダ・・・」とか考えてた。


そしこの前書いた「リトル・フォレスト」に書いてある野菜の献立を見て、今度何を作ろう、とか考えている自分がいる。


近況→足



ちょい前に足に◯KEAの本棚の板を落として爪をはがしたわけですが。その時にはちょっとさすがに動転しててあまり書けなかったのだけれども、あとからよくよく考えるにこの板の側面がちょうど爪の根元に当たって前方向に滑った結果爪を根元からはがす事になった模様。というわけで爪が割れたとかではなく、今は本当に根元から右足人差し指の爪がないわけです。


一応例の高い絆創膏が効いてるのか、昨日から絆創膏もはらないで出歩いてる。ただ、痒い。爪の根元がないから根元の皮の部分があまってふにゃふにゃ。爪はちゃんと生えてくるのかなぁ。


Virginia Tech




http://www.youtube.com/watch?v=OHz0RkKHmtg



怖いなぁ。俺の大学でこういう事起こってたら本当逃げるところなかったよなぁ。アジア人が犯人だということなんだけど・・・例えば俺は人種は関係ないのは知ってるし、人種が関係あったとしても日本人と韓国人ではまた違うってのも知ってるし、別にどうにもならないのだが、アメリカという国は東海岸や西海岸の都会以外では依然「思い込みの激しい」人達が多くて、大きなくくりで同じアジア人として見られて問題になったりと色々あったりするのが怖いなあ。


幸か不幸か、とりあえずバージニアには知り合いはいない。


HTML::FormFuとData::Visitorで動的な値を使う



HTML::FormFuではYAML形式とかでフォームを指定できるのがとってもイイ!のだが、これはこれでデータベースに入ってるリストをプルダウンメニューとして表示したい時とかに困る。特にCatalyst::Controller::HTML::FormFuを使って、FormConfigとかでキレイに組み込む事ができるのにコードを書かなくちゃいけないなんて・・・ということでCatalystではModelが使えるのに着目して、FormFu Modelを作って、Data::Visitorで値を動的に変更する仕組みにしてみた。


以下のコードを使っておけば、



- type: select
options:
- group: dynamic.foo.values

みたいな感じで、dynamicで指定された内容が置き換えられるので、好きな値を動的に吐き出せばいい。結構重宝してる。


# 前提:HTML::FormFuを使える。Catalyst::Plugin::Cacheとかでcacheが使える
# Data::Visitorが使える。

package MyApp::Controller::Foo;
use base qw(Catalyst::Controller::HTML::FormFu);

sub foo : FormMethod('form_config') { }
sub form_config {
my ($self, $c) = @_;
return $c->model('FormFu')->form_config('path/to/config.yml');
}

package MyApp::Model::FormFu;
use base qw(Catalyst::Model);
use Data::Visitor::Callback;
use YAML::Syck qw(LoadFile);
__PACKAGE__->mk_accessors($_) for qw(context);

sub ACCEPT_CONTEXT
{
my ($self, $c) = @_;
$self->context($c);
$self;
}

sub form_config
{
my $self = shift;
my $file = shift;
my $c = $self->context();

my $cache = $c->cache(backend => 'parts');
my $config = $cache->get("model.formfu.form_config.$file");
if ($config) {
return $config;
}

$config = $self->load_config_from_file($file);
$cache->set("model.formfu.form_config.$file", $config);
return $config;
}

sub load_config_from_file
{
my $self = shift;
my $file = shift;
my $c = $self->context;
my $path = $c->path_to(qw(root formfu config), $file);

my $config = LoadFile($path->stringify);

my $re = qr{
^
dynamic\.([\w_.-]+)
}x;
my $v = Data::Visitor::Callback->new(
plain_value => sub {
my ($visitor, $value) = @_;
if ($value !~ /$re/) {
return $value;
}

my $method = $1;
$method =~ s/\./_/g;
return $self->$method;
}
);
return $v->visit($config);
}

git



jrockがMLで問題提起してた。なんかまたややこしいスレッドになりそうな予感がする。



http://ja.wikipedia.org/wiki/Git


http://www-06.ibm.com/jp/developerworks/linux/060809/j_l-git.shtml



Gungho 0.04



rev 61でリリース!ログレベルの変更、Gungho::Inline, Gungho::Provider::YAML, あとはEngine::POEでコンテントを勝手にデコードしないようにするパッチとかを入れましたよ。


リトル・フォレスト





リトル・フォレスト (1)

リトル・フォレスト (1)








リトル・フォレスト 2 (2)

リトル・フォレスト 2 (2)







読んだ。こういう生活憧れるなぁ。食うために仕事する、それだけでもいいじゃんね。


Class::C3::XS - ktkr




http://search.cpan.org/~blblack/Class-C3-0.15_02/



キタコレ。個人的にタイムリー。p5pでC3をPerlコアに入れる話もあったから、その時のコードをベースにしたのかな?


Text::MeCab 0.16



$node->format()って入れた。これでnode-formatとかが使えるはず。相変わらずall-morphsの件は謎。0.15でアップする予定が、0.16にしちゃった。ごめんなさい・・・


最近ちょっと暇



最近お仕事がちょっと暇。そのおかげでCPANモジュールをばんばんアップできてるわけですが。お仕事あったら声かけてくださいまし・・・


Gungho::Inline - GJ!



おお、いいと思います。



http://labs.cybozu.co.jp/blog/kazuho/archives/2007/04/gungho.php



コードの細かいところをまだみてないですけど、そういう事やりましょう!


追記:とりあえずrev 56で取り込んだ!ありがとうございます!


Text::MeCab --all-morphs



formatNode()に対応するために内部構造を変更中。でもなんでだかall-morphsがウマく動かない。なんでやねん。0.15_01としてこのまま出してしまうかも。


Data::Visitor::Encode 0.05



スカラー型のオブジェクトに対応できてなかった。修正。


週末



鯛のアラでお茶漬け作った。ご飯に鯛の出汁とほうれん草、水菜、じゃこ、ネギ。でも海苔入れ忘れた。タマネギと豚ひき肉でケチャップご飯つくってオムレツ作った。相変わらずうまくまとめられない・・・。どうした、俺。ハナマサで赤身メインのサーロイン買ってきてステーキ。付け合わせはお茶漬けの具の残りの水菜の他には粉ふきいもと人参のグラッセ。


先週怪我を負わせられた例の棚もようやく作った。なんかようやく家らしくなった。


PoCo::Client::HTTP decodes content (w/o Permission)



こりゃきづかなんんだ。PoCo::Client::HTTP 0.80でこんなんでてる。



2006-10-25 06:55:14 (r294) by rcaputo
lib/POE/Component/Client/HTTP.pm M; t/14_gzipped_content.t A; MANIFEST
M; Makefile.PL M; lib/POE/Component/Client/HTTP/Request.pm M

Apply Rob Bloodgood's patch to transparently decode non-streaming
content before it's returned. This gives us support for gzip
compressed content. Resolves long-standing rt.cpan.org ticket 8454.

PoCo::Client::HTTPでGETしまくってたら、一部のサーバーのどの日本語ページも$res->content_typeの文字コードと実際の文字コードが合わなくておかしいと思ってたんだけど、こういうことだな?多分0.80以降のXangoベースのアプリも壊れる予感。


うぅ、こいつは小さな親切、大きなお世話の類いだな・・・GunghoではしょうがないのでPOEエンジン内で、またエンコードしなおすという荒技を使う事にしてみる。



# Work around POE doing too much for us.
if ($POE::Component::Client::HTTP::VERSION >= 0.80) {
if ($res->content_encoding) {
my @ct = $res->content_type;
if ((shift @ct) =~ /^text\//) {
foreach my $ct (@ct) {
next unless $ct =~ /charset=((?!utf-?8).+)$/;
my $enc = $1;
require Encode;
$res->content( Encode::encode($enc, $res->content) );
last;
}
}
}
}

これ、オプションにしてくれればいいのに。


Twitter::Shell



Twitter::Shell書いた。これであなたもコマンドラインからTwitterに参加できまっせ。



./script/twittershell

twitter> say Type your message here!
update ok

twitter> friends_timeline
[Daisuke Maki] Type your message here!
....

みたいな感じで。


twitter



とりあえずやってみた。ってか、これ友達登録してないと意味茄子ですね?


シード



夜中にガンダムSEEDの再放送がやってるんだけど、中間の総集編を早送りでみたらようやく話の内容がわかってきた。結構おもしろいな・・・


Gungho 0.03!



スロットリング、認証、それと実験的なDanga::Socketエンジンを搭載。examplesディレクトリもちょろっと書いてみた。使ってくれると機能が勝手に増えて行くと思うので是非試してみてくださいまし。


今日も勝利



ゴミ収集車に勝った。


機械翻訳はまだまだだなぁ



Ben Folds Five の"Brick"の歌詞がなぜか日本語で書かれてるサイトを見つけた!と思ったら、どうも機械翻訳をしてあるだけであとはユーザーが勝手に編集しろということらしい。元の機械翻訳が秀逸?なので一応残しておく。あとで訳そうかなぁ。



http://www.lyricsfreak.com/b/ben+folds+five/jpn:brick_20016573.html



クリスマスの後の6 AM日
私はある衣服を投げる
暗闇
風邪の臭い
カー・シートは凍っている
世界は眠っている
私は無感覚である
彼女のアパートへの階段の上
彼女はソファでballedある
彼女のお母さんおよびお父さんはダウン状態になった
シャーロットに
私達を見つけるTheyre家に

そして私達は運転する
私が創設する誰かを持っているので
単独で感じるIm
私はより前に持っている

コーラス
Shes煉瓦およびIm浸る
ゆっくり
海岸およびImを離れて先頭に立つ
どこも
Shes煉瓦およびIm浸る
ゆっくり

彼らは7:30で彼女の名前を呼ぶ
私は駐車場のまわりで速度を計る
それから私は彼女を買うために歩く

そして私が得たあるギフトを販売しなさい
あなたが見る傾斜
そのない私のために死ぬyoure
単独で感じる今shes
彼女はより前に持っている

コーラス

週が過ぎたように
彼女が良くなかったことを示した
それらは私に息子を時間告げた
真実を言うため
そして彼女は破壊し、私は壊れた

原因Iはあることに疲れていた
彼女のアパートに戻って運転
一時的にだけあった
単独でShes
そしてImだけ
今私はそれを知っている

コーラス

HTTP::Request Formatting



LWP::UserAgent->request($request)とかで簡単にほげほげーっとHTTPメッセージできちゃう、ってのに慣れすぎてるせいか、新しいGunghoエンジンとかを書きたいと思った時に簡単にHTTP::Request -> 実際のHTTPリクエスト文字列へ変換してくれるモジュールがなくて困る。実体はLWP::Protocol::httpとかに入ってるんだけど、これはこれで結構大仰なコードなんだよねぇ。


しょうがないからパクるか・・・。


Gungho - Throttling Enabled!



ちょっと慌ててリリースしすぎた。0.02_02から0.02_04は駄目駄目リリースだったのでこれから削除しますが(


このリリースからProvider→Gungho→Engineの流れが変わったので色々トラブっちゃったわ)、ともあれ、0.02_05以降でGunghoでスロットリングできるようにしました。設定に



component:
- Throttle::Domain
throttle:
domain:
domains:
- match: \.hatena\.ne\.jp$
max_items: 5
interval: 10

とするとはてなに関しては10秒間に5回までしかアクセスできなくなります。


EWPlagnetでPlagger::Plugin::Aggregator::Gunghoで試したら明らかにXangoより速い気が。まぁ体感速度だし、これから機能を足して行くとどうなるかわからないが。このまま問題がなければ今夜か明日には0.03としてリリース予定。


早くAPIを確定したいなぁ。


うーむ



足が痛い。寝てる間にぶつけたか・・・?



http://www.jnj.co.jp/consumer/bandaid/products/medicaltools/power_pad.html



こいつでずっと傷口をふさいでおります。さきほど爪をはがしてから初めてバンドエイドをとってみたら、なんといきなり痛みが。これ本当に痛みを和らげる効果が確かにあるんだねぇ・・・。優秀優秀。


お疲れさまでした。



今日もアホみたいにJavascript書いてしまった。明日はGunghoのThrottlingを書こうと思います。


Catalyst Chained Dispatch



俺、やっとCatalyst Chained Dispatchのコントローラー間のチェーンの仕方がわかった。アホだ。


Gungho 0.02_01



WWW-Authenticate対応のGungho、先ほどアップロードしたっす。


Plugin vs Components In Gungho



k.daibaさんからGunghoでWWW Authenticateしたい旨のリクエストをいただいたので、早速実装しました。細かいところはだいたいLWP::UserAgentのパクリですが。で、これを実装するさいに考えたのが、Authはプラグインでできるのか?と。


Authが組み込まれていると組み込まれていないとではエンジンの挙動が違うのだ。これってプラグインで担うにはどうかなぁ・・・と思ってとりあえずプラグインというものとコンポーネントというものに分けてみた。宮川さんも話してた通り、plugin != componentなのでとりあえずpluginはあくまでplagger風味=フックから呼ばれるもの、コンポーネントはGunghoの挙動をDBIx::Class風味に変えるものとGunghoの中で定義して、



  • Gungho::Component::Authentication

  • Gungho::Component::Authentication::Basic


を作った。いままでGungho::ComponentはGunghoの中で使うオブジェクトとかのベースクラスだったのだが、これに相当するものをGungho::Baseとし、Gungho::ComponentはGunghoの@ISAにインジェクトできるもの、としてみた。


コンポーネントは設定ファイルの中にこんな感じで定義



---
credentials:
basic:
-
- http://example.com
- 'Admin Only'
- admin
- password
components:
- Authentication::Basic

あと、エンジンの挙動を変えるのでエンジンに「この機能持ってる?」とクエリする機能が必要になったのでとりあえずGungho->has_feature($X)っていうのを作ってみた。


http://gungho-crawler.googlecode.com/svn/trunk/Gunghoのrev 29で実装済み。


道玄坂シャルマンは行かないほうがいいよ。



俺は結構店とかにたいしてぶちぶち文句は言う方だとは思うけど、まず滅多に2度と行かないとか、救いようのない事は言わない(はず)。けど今朝コードを書きたかったので寄り道していた道玄坂のシャルマンという店は感じ悪くて二度といきたくない。まぁPCをパチパチ叩いてたし、結構長めの時間をいたので文句を言われてもいいのだ。必要だったらもう一杯頼むしさ。でもまがりなりにも客に物を言う時にさ、肩を叩くか?「お客様すみませんが・・・」だろ?しかも理由が「うるさい」だぜ。おまえがさっきから大声で話してた常連どものほうがよっぽどうるさいわ。


おまけに今日はモカは480円が→430円になるはずだったのにアイツ値引きしなかった。ひどい。あ、あとお金払った時に「ありがとうございました」って言われなかった。どういうことじゃ。


常連相手でだべってる商売はいかんな、やっぱり。


L3



Yeah, so what if I'm a bit drunk. love, love, love. that's all I got for you.


UTF8 = ”Ugh, That F**ked me over 8 times!”



XSを書いていて、Perl内部での扱いがすげぇ難しいという事によーやく気がついた。くそぅ・・・Text::MeCabもこれで大分問題が起こってると推測。くそ・・・これはもう最初から文字コードとか、UTF8フラグだとかをユーザーが指定できるようにするしかないような。


メモ - Text::MeCab



mecabの引数の--node-formatとかはMeCab::Writer内で内部構造→文字列化される。mecab_node_format()に渡せばOK。問題はClonedなノード。PurePerlでやるか?あとWriterはMecab内の先頭ノードと最後のノードを見ない。理由は不明だけど、多分リスト構造の目印的な扱い。


Text::MeCab0.15でのハック



--node-format= "%m %pn %pw"

for (my $node = $mecab->parse($text);
$node;
$node = $node->next )
{
next unless $node->surface; # 先頭と最後のノードを排除
print join (" ",
$node->surface,
$node->cost - $node->prev->cost,
$node->wcost
), "\n";
}

うーん、cloneノード用をC++レベルでフォーマットしてもらうより、PurePerlで書いた方簡単な気がしてきた。


Gungho + Plagger



個人的にやってるEWPlagnetをGunghoベースで動かし始めた。0.02 + alpha G::Provider::Simpleがis_running(0)しないと行けない問題だけ0.02にで解消されてないから。


Request Timerを見る限り、PoCo::Client::HTTPのキュー待ちで最後のほうのリクエストが1秒以上かかってるように見えるけど、どれも基本的には0.2秒以内に収まってると思う。まぁただのGETだしね。


Gungho Plugins



Gungho 0.02 で YAPR (Yet Another Plagger Ripoff) Pluginシステム書いてみた。とりあえずひとつひとつのリクエストがどれくらい時間がかかってるのかわかるようにRequestTimerっての作ってみた。



---
plugins:
-
module: RequestTimer

Gungho 0.02は先ほどアップロード。


気合い気合い



生爪はがし事件その後、まぁびっこ引いてるけど、別に激痛というよりかはあの詰めの無いところに靴があたるいや~な感触を抑えるため。あとはまぁ気合いだ。大丈夫っ


痛ッッッッッッ!



やっちまいました。某IK◯Aの本棚を組み立てようとしたら、うっかり木の板を思いっきり右足人差し指の真上に・・・思いっきり生爪はがして、血がどばどばでますた。うごけねぇよ、これじゃ。


Gungho 0.01



0.01をリリース。API変更が少々。Plaggerでの挙動を修正。


疲れ。



なんか、体がそーとー疲れてる事を認識。今日は家でだらだらするかなぁ・・・ひさしぶりかも>だらだら


Gungho



PoCo::Client::Keepalive で接続をプールできるようにしてみた。そろそろ0.01にするか。


Gungho



YAPCに触発されて新しいクローラーフレームワークに着手。まだまだ出来てない部分はあるけど、一応もう動くよ。



http://gungho-crawler.googlecode.com/svn/trunk



あとついでにPlaggerのAggregatorも書いた。Xangoではメモリではなくファイルにデータを書き出すとか、最適化をはかったけど、今回のはとにかく作り込みやすさのほうを念頭に。だから多分今のXangoより遅い+メモリは食うとは思うけど、こちらのほうがなんか明らかにコードがキレイだ。



package Plagger::Plugin::Aggregator::Gungho::Handler;
use strict;
use base qw(Gungho::Handler::Null);

__PACKAGE__->mk_accessors($_) for qw(gungho_plugin);

sub handle_response
{
my $self = shift;
my $c = shift;
my $res = shift;

$self->next::method($c, $res);
$self->gungho_plugin->handle_feed($res->request->uri, $res->content_ref);
}

package Plagger::Plugin::Aggregator::Gungho;
use strict;
use base qw(Plagger::Plugin::Aggregator::Simple);
use Gungho;
use Gungho::Request;

__PACKAGE__->mk_accessors($_) for qw(requests);

sub register
{
my ($self, $context) = @_;
$context->register_hook(
$self,
'customfeed.handle' => \&accumulate,
'aggregator.finalize' => \&aggregate,
);
$self->requests([]);
}

sub accumulate
{
my($self, $context, $args) = @_;
my $url = $args->{feed}->url;
return unless $url =~ m!^https?://!i;
$context->log(info => "Fetch $url");
push @{ $self->requests }, Gungho::Request->new(GET => $url);
}

sub aggregate
{
my ($self, $context) = @_;
my $g = Gungho->new({
provider => {
module => 'Simple'
},
handler => {
module => '+Plagger::Plugin::Aggregator::Gungho::Handler'
}
});
$g->provider()->requests( $self->requests );
$g->provider()->has_requests( 1 );
$self->requests([]);
$g->handler()->gungho_plugin( $self );
$g->run;
}

1;

ユメとか飯とか



さて、YAPCで疲れたからでしょうか。いやに生々しい元カノの夢をみてしまいますた。連日の酒のせいですかね・・・今日も約束があるので今日を休肝日というわけにもいかないので肝臓にシジミの成分をあたえるべくひとっぱしり魚力まで。今日は多分2番目の客だったのでまだイサキがあったよ!イサキ、でかいよ。丸ごとだよ。でも今日は味が微妙に薄めだったよ。


YAPC - おつかれさまでした。



正直あんまり役に立ってなかったけど、今年もお手伝いスタッフとして参加してきますた。自分のスライドは本番1時間前に終わったさ!charsbarさんは発表5分前に完成させてたけど!あと表にはでてなかったけど、刺身ブーメランさんとかablaboさんとかnTeTsさんとか、ほんとにお疲れさまでした。


それでは来年こそは沖縄で。


にぽたん



サスペンダーもだけど、声が激似


CDBI -> DBIC



Jifty::DBIを使え、と。


あと1時間で俺の番なんだけど



VGA接続しかできないことを発見!またかよ!


劉さんが持ってた!ありがとう!


ボランティアするって言ってるのに



緊急出動かかってて、YAPCにいけない・・・自分の出番までには行きます!


Liquid Room



YAPCスピーカーのDaveがBEATCRUSADERS見たいというので大分前からオークションでチケット取ったりしてて、ついでに一緒に行ってきた。ちょっとセットは短かったけど、結構おもしろかったなぁ。


これも逃避か



YAPCに来ると突然コード書く必要がでてきたりして。今はRSS出力かきました。


はてなガム



味は普通ですた。


YAPC 2007



きてますきてます。MJD初めて見たよ!来てる間にData::Validate::Japaneseもリリ-スしてみたよ!←現実逃避


utf8-flag considered harmful.



最近P5PをにぎわしているUTF-8 フラグですが、どうも俺もHTML-FormFuを使ってたらこれに悩まされ始めて、とうとう全て取り外した。つーか、最初っからこうすればよかったんだよね・・・全く反対方向につっぱしってたわ。


外山恒一、バロス



373君が横で見てたらはまった。これはおもしろい



http://www.youtube.com/watch?v=l2C9lv5t0yQ


http://www.youtube.com/watch?v=pLTdaBAfwBY



ドラゴンボールZのBGMのヤツはもう芸術です。これはアート。


一体今日は何月なんだ。



YAPCのスライド書きながらふと寒いなと思ったら、9度?9度ですか??寒すぎるだろ・・・


あさってはYAPCですよ!



スライドが全然できてなくて、さすがに焦ってきた。現実逃避ばっかしてます。


ネコマネ@下北沢



ぴょん子が常連の岡山のバーの系列店(まぁそういうことにしておく)が昨日下北沢の店がオープンするというので、主に岡山店の従業員の知り合いに挨拶しに。なんかまだ店が本当にできたばっかりで(その日の朝に内装が終わったとか)結構バタバタしてた。内装とかは岡山の店の雰囲気が残ってる感じ。最後のほうは隣に座ったおねーさまと話しつつ、12時過ぎに退散。


やっぱシャンパンは効く。


パフューム



「パフューム」見てきた。妙な迫力のある映画だった。意外と大物俳優が出てきててびっくり。これは結構おすすめよ。



Author

Daisuke Maki (a.k.a lestrrat): Perl hacker, Director of Japan Perl Association, YAPC::Asia Tokyo Organizer (2009-2012), Fluent in Japanese, English. Ex-Brazilian (sorta)

#perl #c #ruby #java #mysql #english #japanese #opensource #stf #cooking #scotch #cigar


このエントリーをはてなブックマ
ークに追加

翔泳社よりモダンPerl入門(2010)を出版させていただいております。できれば内容をアップデートしたいので是非皆様・・・現在の在庫処理にお力をお貸しください!><

月別アーカイブ