2006年5月アーカイブ

会社のコミュニティを作ってみる。



mixiで会社のコミュニティを作ってみた。そして最初の書き込みが麻雀大会のお知らせ。なんだ、この会社。


デュアルディスプレイ



期間限定でDELLの20インチディスプレイが4万円弱も安くなってたので購入。ビバデュアルディスプレイ。


f:id:lestrrat:20060531130849j:image:w100


ワインとチーズ



従姉妹がなんか送ってくれたー。イチジクとかも入ってる!わーい。


Jcode vs Unicode::Japanese



ハテナオヤさんのはてブでみたUnicode::Japaneseなんだけど、とりあえずベンチマークをとってみたら



daisuke@beefcake daisuke$ perl benchmark/h2z.pl
Rate unicode_japanese jcode
unicode_japanese 1236/s -- -32%
jcode 1825/s 48% --
daisuke@beefcake daisuke$

おりょ、Jcodeのほうがかなり速いね。こんな感じのコード。ふーむ。


    my $obj = Jcode->new($str_h);
    my $z   = $obj->h2z->euc;

$obj = Jcode->new($str_z);
my $h = $obj->z2h->euc;
}

sub unicode_japanese
{
my $obj = Unicode::Japanese->new($str_h);
my $z = $obj->h2z->get;

$obj = Unicode::Japanese->new($str_z);
my $h = $obj->z2h->get;
}

cmpthese(10_000, {
jcode => \&jcode,
unicode_japanese => \&unicode_japanese
});


lighttpd + FastCGI + Catalystを試してみる



逃避とか色々かねて、以前より懸案だった「モニター、キーボード、マウスのついていないMac Miniで皆の音楽をためて、コントロールする」という事を実装した。で、小さいプロジェクトだし、割とストレートにできそうだからlighttpd + FastCGI + Catalystを試してみた。


ちょっとハックが必要だったのがMac::iTunes。まずなんもドキュメントに書いてない!get_current_track_artist()とか存在さえも隠蔽されてる(笑)Security through obscurityかっつーのw。あとはプレイリストの内容を表示するのにget_track_names_in_playlistを直接ハックして


(良い子の皆さんはまねしないように)ページングできるようにしてみた。基本的にはAppleScriptの内容をこんな感じに変更:



# 前提:ユーザーから$limit, $offset, $playlistを指定してもらう

my $script = <<"SCRIPT";
set myPlalist to "$playlist"
return count of tracks in playlist myPlaylist
SCRIPT
my $psize = $self->tell( $script );

if ($limit > $psize) {
$limit = $psize;
$offset = 0;
} elsif ($limit + $offset > $psize) {
$limit = $psize - $offset;
}

my $start = $offset + 1;
my $end = $offset + $limit;

$script = <<"SCRIPT";
set myPlaylist to "$playlist"
set myString to ""
repeat with i from $offset to $end
set thisName to name of track i in playlist myPlaylist
set myString to mystring & thisName & return
end repeat
return myString
SCRIPT

my $result = $self->tell($script);
my @list = split /\015/, $result;
return \@list


これをApp::Controller::iTunes からたたく:



# play / pause / stopとかは全部一緒
sub play : Local
{
my($self, $c) = @_;
my $itunes = Mac::iTunes->controller;
$itunes->play;
$c->response->redirect('/itunes/status'); # 現在の状況を表示ページ
}

sub library : Local
{
my($self, $c) = @_;

my $itunes = Mac::iTunes->controller;
my $page = $c->req->param('p');
my $limit = 100;
my $offset = ($page - 1) * $limit + 1;

# ↓ちょっとこの辺の呼び出し方はてきとー
my $list = $itunes->get_track_names_in_playlist('Library', 100, 0);

my $position = $offset;
foreach my $name (@$list) {
# トラック番号がないと後でどーしようもない
push @tracks, { position => $position++, name => $name };
}
$c->stash->{tracks} = \@tracks;
$c->stath->{template} = 'library.tt';
}


こんな感じ。テンプレートはまぁ想像できるんじゃなかろうか。で、あとはlighttpdをどこん、と起動しておしまい。Mac::iTunesのソースコード(特にMac::iTunes::AppleScript)を読まなかったらきっとなんもわからんかった。ぼへぼへ。


仕事。



なんかロシア人が俺のパッチ使えとうるさかったので、Class::DBI::Pgリリース。0.08_02文句が出なかったらこれで0.09にする。


某社に納品。某社のDBいじり中。時間かかりそう。某案件のマルチスレッド部分にタイマーを仕掛けてみてる。pthreadわけわかんね。


某バーテンさんにメール。DB作りたい作りたい。某案件のデータベース構築、一部のデータ入力が完成。やった。


わー



超落ち込んできた。友達の人妻とエロトークしたら大分収まったw


朝コーディング



朝のコーディング時間。やっぱこの2時間は使わないと損損。


住所等を抜き出すプログラムを書きながらTV。「黒バラ」でかつらボクサーの話題の間になぜかBGMが「とくダネ!」。ワロス。トランスポーターの女の子、かわいー。


べつやくれい



べつやくれいの「ココロミクン」購入。おもろ。


またバー



思ってたより心が折れてたので、連荘でバー。コニャックとか色々飲みつつ葉巻。葉巻は色々試してみてきていたが、やっとうまい!と思うものに出会えた。Romeo y Julieta のリザーブ。これはうまい。葉巻の味がちょっと唇に残り、甘くてうっとり。


帰りに亀屋がしまっててちょっと残念。モルトがらみのビジネスしたいなぁ。


そろそろ



潮時かと思いますよ!そろそろ引くデス。いい感じだったけどね。


メモ




  • MySQLにテーブルサイズとクエリ発行数のトレードオフってのはどんなんだろう。

  • 今日のおべんきょ:一キロ範囲は緯度経度でざっくり区切ると、約44秒x32秒になるのでこれで計算できる。

Life Wasted



Perl Jamの新譜ビデオがグーグルビデオにあったと。これ、久しぶりにいい感じの曲だなー。弾きたい、弾きたい。


出発進行



書いたのに消しちゃったよ。


Data::FormValidator使って、多分初めて(!)「まとも」なフォームを書いた。いやぁ、意外と面倒くさいな。コマンドラインツールのほうが好きだ、俺(笑)


ともあれ、これでデータを流し込む作業開始できる。次は流し込むバイト探し。ついでにプログラムもかけるいいバイトいねぇかなぁ。


Class::DBI::Loader 0.33



サジェスチョンがあったので"require"というパラメターを実装した。動的に生成されたモジュールに対しての実ファイルがあった場合にrequireするというもの。以前Module::Pluggableで俺がやったのと基本的には一緒。ただし、今回実装したのは動的に生成されたモジュールに対してのみ。俺の以前書いたヤツはあるネームスペースに存在するものを全てrequireする。


あれ、なんでこんな時間



バイト探し関連で飯食って1時過ぎに家に帰ったのだけど、今4:59。あ、あれ・・・


プール



ざばざば。先週はプールが清掃中とかでいけなかった。今日はゆっくり目にざばざばと。やっぱここのプール人が少なくていいわ・・・


メール



帰り際にメールが来て(多分特に用無し状態においては初めて)ちと会話。すげぇ舞い上がったのだが、やっぱり何回考えても「これって・・・高校生状態だよな・・・」と自分の挙動を反省。


萌え




http://d.hatena.ne.jp/higepon/20060520/1148107781



俺も読まそう・・・って読ます相手いねぇし!


マグロの煮付けがうますぎる



俺の作ったマグロの煮付けがうますぎる。本当にうまい。く、今日は日本酒がない・・・


サイクリングサイクリング



渋谷→南青山→皇居→虎ノ門→麻布→広尾→渋谷と、サイクリングでぐるぐる。楽しかったが、皇居に行く前の山王坂でなんかバテてしまってた。皇居外苑でぼーっと休んだりしつつ。途中ビックカメラでパーフェクトグレードZガンダムのプラモ買いそうになってやばかった。1万4000円超って・・・お昼は有楽町の「タベタ」でタイ料理、630円。


帰りに日比谷公園でアフリカンフェスタやってた。でもオーガナイザーがあまりうまくないと見えて混み過ぎ。駄目駄目。


渋谷でモッツァレラ・ディ・ブッファーラ、ホタテ、マカロニサラダを購入。エビス飲みつつモッツァレラ。うまー。マグロの血合いが100円くらいで大量に売ってたので生姜で甘辛くにつつビール。ホタテ。うま。


あとは高菜の漬け物を買ってあるのだが、これは高菜、小松菜、豚肉で炒め物を作ろうと思っている。今日できなかったら明日の夕飯。


POE::Component::Client::KeepAlive



Xangoで見てたエラー、絶対これだ



2006-05-09 06:11:06 (r58) by woggle
t/51_reiss_reuse.t A; Client-Keepalive.pm M

Fix bug and add test case for bug where a socket would be reused and
then free'd by _ka_wake_up when we were at the connection limit.


電話



3時間くらい悩んで電話したのに留守電になると悲しいorz。さて、そんなおいらは自転車に乗って皇居にでも行こうかと画策しております。


モルト祭り



馴染みのバーでイベント。ラフロイグとボウモアのオールドを一杯ずつ(これだけですでに普段の予算の8割(笑))その後飲み放題でエルギンやらオーバンやらふだんから全然飲まないヤツをぱかぱかと。タリスカーをタリスカーのバカラグラスで2杯(このためだけにロック)。あとはラガブーリン、ラガブーリン、ラガブーリン。


EucJP-MS




http://www.mysql-partners-jp.biz/techinfo/tech_01.html



後で読む。確かjcode MLで~の変換についても誰かが話してた。実際の挙動はどうなのだろう。後でまた良く読んでから考えるけど、問題はこのエンコーディングが追加された事で実際にはどうコード書けばいいのか、ってことかな。


ちなみに(コレ書くと弾さんがすごい喜びそうだけど(笑))Encode::GuessやEncode::Detectを使って色々ホゲホゲしてるとJcodeが一番信用できるという結果に俺は落ち着いてる。例えば「傳田」という言葉をEncode::GuessとEncode::Detectで使ってみたら化け化けらった。Jcodeだとばっちり。


なんなんだと思ったけど、よくよく考えるとEncode::*のほうはあくまでも全てのエンコーディングに対応するけどJcodeのほうは日本語に特化してるから判別もできるんだろうなぁ。


yomi.endeworks.jp



うちのスタッフの方達が、ちょっといい感じのデザインを作ってくれたんおでhttp://yomi.endeworks.jpをぷちリニューアル。グッジョブだ。


誰か俺にAppleScriptを教えてくれ!



brian d foyのMac::iTunesとかをお手本にしてiTunesをコントロールするやりかたはだいたいわかったんだけど、どうしてもトラックをライブラリに足す、という作業ができん。



set myName alias ":path:to:file"
add myName to Library

とかやってみるも全然うごかん。一体どうやったら任意のファイルをiTunesライブラリに足せるのーーー??


はてなダイアリー編集画面



画面が切り替わる瞬間にアクセスしたらしく、いきなり画面が変わってビビった。プレビュー機能カッコいい


お祝いではないが



ケーキを食べるペンギン3匹


若人に会ってきた。



ここを読んでるのかどうかしらんが、大分ストイックなエンジニアだと思われていたようで。まぁでもそういうのってよくあるよね。ちなみにMみ君は昨日の約束通り今日から1時間に1回ちんこネタを振るように。


日付間違ってた



昨日の分の所に日記書いてたよ。Data-Average 0.02アップロード


ネット(また)重い



エ~ヌティ~ティ~・・・一体なんなんだ、このネットの重さは!最近多すぎ。仕事できんやないか。




ERMEYERSという人が作ってるモジュール群。最悪。ひでぇと思ってたけど、Makefile.PLの中にあったこのコードで戦慄:




my $param =
{
'NAME' => 'WWW-Blogger',
'AUTHOR' => 'Eric R. Meyers <snip>',
'VERSION' => Date::Format::time2str( '%Y.%m%d', time() ),
'LICENSE' => 'perl',
'ABSTRACT' => 'Interface to www.blogger.com',

};

http://search.cpan.org/src/ERMEYERS/WWW-Blogger-2006.0516/Makefile.PL



えーと。Makefile.PLだから・・・俺が今日インストールするとバージョンが2006.05.16で、明日インストールすると2006.05.17・・・。唖然としすぎてコメントが思い当たらない。ちなみにこの作者の他の傑作モジュール:



WWW-YouTube-2006.0516


Bundle-Modules-2006.0516



・・・ひでぇ。




とりあえずリリース。Data::AverageはXangoで使う予定。


ところでEncode::Detectなんだけど、止まってます。わははh。いやー、すでにCライブラリ化されてるヤツがあるじゃん!って事と、あとWin32サポートがText::MeCabで随分面倒くせぇなぁと理解しはじめてきたのでどうしたもんかと。



http://rt.cpan.org/Public/Bug/Display.html?id=16250



id:kazeburoさんの所で見つけてきたこんなバグなんかを見てるとテイクオーバーするくらいの勢いでやりたいなぁと思ったりもするんだけど・・・Win32サポートが・・・


MTVのVMAS入場券あたった。



わほ。やったー、と思ってたら



  • 整理番号順に入るのみ

  • 「満員の場合は入場をお断りする場合が・・・」だって


なんじゃこりゃ。まぁいいけど・・・。相棒ちゃんが調べてくれたところ:



収容人員 13,753名


スタンド席9,079名/ロイヤルボックス88名/アリーナ席4,586名


http://www.naash.go.jp/yoyogi/ichitai_sisetu.html



との事なので、俺の番号は相当後のほう。う~ん。


TV



久しぶりにテレビ見た。あいのり、キラキラアフロ、くりぃむ、浜ちゃんと。もうあいのりは誰が誰なのかわからん。


偽物



今日はちょっと堅い格好をする必要があったのでスーツ。似非サラリーマン、っつーかほぼコスプレ状態。


Data::FormValidator::Constraints::Japanese



Data::FormValidatorに手を出してみた。結構いい感じ。FormValidator::SimpleがLyo Katoさんの手によって出てるのは気づいたが、とりあえずD::FM使おうと思ったので先ほどData::FormValidator::Constraints::Japaneseをアップしてみた。


母の日なので



親の誕生日も近かったし今日は家族サービスで半日潰す予定


タイフェス



・・・結局来ました。雨のわりに意外と盛況。晴れてたらもっとビールがうまいのになー


雨か・・・



タイフードフェスティバルどうしようかな。


映画



「ドッジボール」見た。バカらしすぎる。おもろ。「THE ISLAND」みた。なんだ、このオチ。


かぶってみました。



もう自分で爆笑。


プール



1年半ぶりくらいにプール行ってきた。渋谷区民ってリッチだな、と思わせる立派な施設が誰が使っても400円。しかも人がいない!空いてる!わーい。ざばざば泳いで1時間くらい。でも1キロも泳げなかった。とほほ。


帰り道に途中にあるお店でお弁当、530円。


ハァハァ



ワンピ素敵。


Perl テストフレームワーク



Test::MoreとかはPerlモジュールをテストするのには十分だが、俺が某社にいた頃にはPerlで製品の全てをテストしていて、さすがにTest::Moreでは限界があり自社フレームワークを使っていた。だけど俺は本当に本当に本当に本当に本当~~~~~~~~~~にこのフレームワークが嫌いだった。いわゆる「ユーザーのわがままを聞き過ぎ」なフレームワーク。なんでもできればいいってわけでもないのに言われる事を全部実装するもんだからもう何がどうなってるのかわからない。


っちゅうわけでそれに代わるフレームワークを書こう書こうと思ってたのだが、会社ではその仕事は禁じられたのでしぶしぶ仕事をサボってDateTime系のモジュールを書いてたりしてた(おいっ)。


んで、今日一日でとりあえず



# test.jpl
use JINN::Test::JPL;

ok(1, "Tests pass");


というコードを書いて



$ jinn test.jpl
+ test.jpl: Passed 1/1
All tests passed

まではできるようになった。これだけだと、Test::Moreと変わらないのだが、まぁとりあえずそこはご愛嬌。このコードだけでは何もわからないけど、



  • テストそれぞれがオブジェクトにもなれるのと

  • 個々のテストの組み合わせを実行できる

  • なおかつ階層的に組み合わせて、テストの中から他のテストを実行できる

  • 様々なマシンに入ってコマンドを実行できる

  • マルチスレッドで動かせる


というのが目標。


IKEA := 最悪決定



えーと。まぁ混乱してたから配達が10日遅れたのは許しましょう。ですが。



  • 皿が全部割れてます

  • カップが1本足りません。


えーと。クレーマーになります、ええ。


WWW-RobotRules-Parser



ちょっと使えると思ったのでとりあえず書いておいた。WWW::RobotRulesは先にUser-Agentを決めてから実行して、そのAgentにマッチするルール以外は全て捨ててしまうが、これはパースした結果をそのまま返すだけだから後で好きなように使える。



use WWW::RobotRules::Parser;


my $p = WWW::RobotRules::Parser->new;


my %r = $p->parse_uri('http://hoge/robots.txt’);



そのうちコレを使うモジュール書く。


XML Feed Sucks



XMLでのフィードはエンコーディングが駄目駄目なのが多すぎる。おまいらちゃんと直せよ。


そういうわけでXMLパーサーにかけるのがあほらしい。こんな時はLWP::UserAgentと正規表現


だ。というわけでスクリプト群を作成中。yahoo! ブログの更新大杉。


AjaxSpy




http://blog.vandev.com/articles/2006/05/04/my-first-tool-for-you



Jesseが後で見るって言ってたので後で見る。


愚案/夢想



あるデータベースAに対して、SELECT/INSERT/UPDATEがひじょうに頻繁に行われる巨大なテーブルTがあるとする。データは常にある特定の条件の元にバルクで取り出される。それをさらにソートなりなんなりしていくので、PostgreSQL上ではsort bufferとwork memを相当消費する。


これをDBレベルで並列化するのはちょっと構造上できないと思うのだが、じゃあテーブルを分割して



T_a


T_b


T_c


...


T_z



とかに分けて、それぞれに対して少ない数での抽出/ソートを行うのはどうだろう。アプリケーションレイヤーかStored Procedureレベルでこれらのテーブルに随時アクセスしていければいいんだが。


タクシーの中で打ってます。



朝、目覚めると同時にメールチェック。また今日もがっくし。昼、毎週/毎日?恒例になりつつある謝罪メール。でもサーバーが落ちるのは俺のせいじゃねぇよ・・・orz。バグなら俺のせいだけど、PostgreSQLで



mydb=# \d


ERROR: cache lookup failed for relation 116890841


mydb=#



なんてエラー、見た事ねーよ。まぁとは言え、しょうがないのでpg_dumpで救えるデータは救って、あとは新規にコンパイルしたPostgreSQLに移してみた。


TODO:



  • Apacheで某アプリのデータ挿入数をカウントする?

  • PostgreSQLでINSERTの数を取りたい。パフォーマンスへの影響を最小にしつつできるのか?

  • PerlレベルでDBIをsafe-failoverさせる仕組みが欲しい。pgpoolはDBD::Pgと相性悪いらしい。


あまり重要じゃないTODO:



  • WindowsでPerlモジュールをコンパイルできる環境がほしい。だれかVC買ってください。


しかし、タクシーの中でタイプしてると車酔いがすごいな。


和式



日本古来の物は大切にしようと常々思っている訳ですが、これだけはいただけません:和式便所。今回旅行に行ったところが和式便所だったため偉い苦労した。こんなところでは集中+リラックスして用が足せないではないか!


俺がちゃんとした使い方を知らないだけか?


数年前。



数年前の事で未だに後悔してる事があって、それは今でも新しいエントリーを読むたびに後悔してる。まぁいいんだけど。


眠い。眠いよ。


ズームインスーパーに遭遇



カレー食ってたらズームインスーパーのクルーが来て取材してた。絶対こっちにこないと思ったのだけど、しっかり感想を聞かれましたよ。とはいえ、メインはカレーうどんだったらしく、俺は食べた事なかったので多分使われないだろうw


IKEA届きません



昨日の午後に電話があったのですが、移動中であったため早々に切った。そしたら今朝また電話がかかってきて、どうやら明日配送の模様。


Text::MeCab検証できない・・・



id:charsbarさんの指摘されてた内容が検証できない・・・よ~くエラーをみたら俺の思ってたエラーと違ったので・・・。Windowsな人が切り分けしてくれるとありがたい。


ただいま



22:50分くらいに帰宅。いやー、疲れた。さて仕事。


禁断症状



今回はネット接続を期待できなかったのでPC持って来てない。48時間近くもネットとPCがないなんて多分10年ぶりくらいじゃなかろうか。


正直 つ ら い


charsbarさんありがとう!




http://d.hatena.ne.jp/charsbar/20060508/1147019251



ありとうございます!Text-MeCab 0.06リリースしました。あとはsearch.cpan.orgさえインデックスを再起動してくれれば・・・


知り合いはっけーん




http://www.rbc-ryukyu.co.jp/rnews.php?catid=9&blogid=4



5/5のインタビュアーは高校の同級生です。一回TBSのメール経由に連絡取ろうと試みたが、その後連絡なかった。わはは。


ついでに発見。がんばってんだなぁ。



http://www.okinawatimes.co.jp/day/200509071300_07.html





以前書いてたEncode::Detectがようわけわからんから、Cにポートしたいって書いたのだが、どうも難しいので他の人と一緒にできるといいなぁ、と。


Encode::DetectのソースはただMozillaプロジェクト内のextensions/universalchardet/src/base内のファイルを全部コピーして、C++ライブラリの上にPerlのXSラッパをつけただけなんだが、これをlibXXXX.soとして単体で動くようにしてEncode::Detectみたいな物をつけたい。


当初のゴールとしては:



  • カッコいい名前をつける(id:miyagawaさん要望w)

  • Encode::DetectがしてるみたいにC++のファイルをまずそのまま使って、Cラッパをつける

  • autoconf等を作成する

  • libXXXXとして単体で扱えるようにする

  • Perlラッパをつける


って事で、その後必要に応じて中身をCにするなりなんなりしていけばいいと思うのだが、どうだろう。一緒にやる人いるかなぁ?


Text::MeCab メモ




daisuke@bl000:~$ perl -MText::MeCab -e 'print &Text::MeCab::MECAB_VERSION, "\n"'
0.81
daisuke@bl000:~$

id:miyagawaさんがエラーでるっていう報告くれたのでチェックしてたのだが、どうもlibmecab 0.81では再現しない。確かオリジナルの報告は0.80だったのだけど、0.80の問題か?


#ちなみに0.80はMac OS Xでコンパイルできん・・・


あと2時間



さて、あと2時間でおいらはおでかけするのですが、寝れません。5時に起きるのに3時近くまで酒飲んで遊んでるなよ、という噂もある。


Text-MeCab 0.05 Released




http://search.cpan.org/~dmaki/Text-MeCab-0.05/lib/Text/MeCab.pm



ようやくdebian (libmecab-devがいまだに0.80)でマトモにテストしたので、id:charsbarさんの要望もあり0.02からいきなり0.05にバージョンをあげてリリース。多分このリリースで落ち着くと思います。


yomi.endeworks.jp



Text::MeCabついでにhttp://yomi.endeworks.jpも左側の「最近の検索」がちゃんと動くように(2ヶ月ぶりに)手を入れた。なんか時々DBエラーが起こるけどご愛嬌。


っていうか、まだCPANからインストールできないから自前のText::MeCab使ってないのも愛嬌。


で、寝れないわけですが



基本的にはPAUSEにアップロードしたText::MeCabがちゃんとsearch.cpan.orgに出てきてくれないと安心できない、って理由で寝れてないんですが。まぁほげほげと色々ある人生なわけですよ。かといってここにだらだら書く内容でもないので(一瞬ppencodeして書こうかとか思った)割愛しますがね。XS語ってる場合じゃねーよw


っていうか、実家に来てるのにかれこれ5時間以上Text::MeCab関連作業してるってどうなのよ。ひょっとして素面だから寝れないのか?←だとするとやば。




PAUSE IDがDMAKIだから「DMAKI氏」とかでリンクされる事が多い最近ですが、俺としては横文字で書かれる場合はdaisuke、普通に日本語の場合は牧がいいですいいです。DMAKIってなんか大学時代の学部サーバーのログインっぽくってイヤン。


MeCabのノードの扱いに困る




http://chasen.org/~taku/blog/archives/2006/05/textmecab.html



で指摘されたように、こんな感じのコードを書くとText::MeCabが困ってしまう。



use strict;
use Text::MeCab;

my $mecab = Text::MeCab->new;
my $node_A = $mecab->parse($TEXT_A);
my $node_B = $mecab->parse($TEXT_B);

for(; $node_A; $node_A = $node_A->next) {
print $node_A->surface;
}


これだと$TEXT_Bの形態素解析が出てくる。ほげぇ。で、思うんだがこれって要は無理矢理OOしてるからじゃねぇの?と。


本当はsemantics的にはこんなんじゃないか?



use strict;
use Text::MeCab;

my $mecab = Text::MeCab->new;

$mecab->parse($TEXT_A);
my $node_A = $mecab->node_instance();


なんかparse()がnodeを返してくると全てのnodeが独自に動かせるような印象を与えられるけど、実際はMeCab::Taggerに対してのインスタンスなんだからちょっと違うよね。OOにしたかったらMeCab側でnodeをclone()するとか、そういう仕組みがあるととても楽なんだけど・・・。ちなみにこんな感じで手動でclone()するのはやってみたけど、segfaultだらけでお話にならなかった:



node = mecab_sparse_tonode(mecab, input);
Newz(1234, tmp, 1, mecab_node_t);
Copy(node, tmp, 1, mecab_node_t);

というわけで悩み中。とりあえずコンパイル問題等を修正した0.02_01を先ほどCPANにアップしておきました!


Text::MeCab とりあえず待って



俺の環境で動くだけでなくて、debianで動くようにしつつ、mocab本体をundefするとnodeが消えるところに警告くらいは入れたいのでちょいお待ちを。


俺ってあまずっぺぇ



どこのポ◯リスエットの宣伝だ。でも俺ってあまずっぺぇ。


More Text::MeCab



0.02_03アップ。今度はprev()が抜けてたのと、テストを足したのがメインフィックス。


Text::MeCab - duplicate nodes



mecab_node_tがすでに解放された後かどうか色々試行錯誤してみたけど、結局よくわからん。もう最後の手段でコピーを作成するのでどうだ、と。というわけで0.02_02ではText::MeCab::Node作成時にC structのコピー(もどき)を作ってみた。それでも速度は2倍くらいだから今の時点ではいい感じのトレードオフかな:



daisuke@beefcake Text-MeCab$ perl -Mblib tools/benchmark.pl
Rate mecab text_mecab
mecab 10.4/s -- -52%
text_mecab 21.7/s 109% --

というわけで、このコードは動きま・・・動くはずです!



use strict;
use Text::MeCab;

my $node;
{
my $mecab = Text::MeCab->new;
$node = $mecab->parse(....);
$mecab = undef;
}

for(; $node; $node = $node->next) {
print $node->surface, "\n";
}


Text::MeCab with libmecab < 0.90



libmecab < 0.90 (debianのaptとかは0.80)は内部構造がだいぶ違ってエラーになる罠:



 ./Build
lib/Text/MeCab.xs -> lib/Text/MeCab.c
/usr/bin/perl "-I/usr/lib/perl/5.8" "-I/usr/share/perl/5.8" "/usr/share/perl/5.8/ExtUtils/xsubpp" -noprototypes -typemap "/usr/share/perl/5.8/ExtUtils/typemap" "lib/Text/MeCab.xs"cc -I/usr/lib/perl/5.8/CORE -fPIC -c -D_REENTRANT -D_GNU_SOURCE -DTHREADS_HAVE_PIDS -DDEBIAN -fno-strict-aliasing -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -O2 -o lib/Text/MeCab.o lib/Text/MeCab.c
MeCab.xs: In function `init_constants':
MeCab.xs:44: error: `MECAB_NOR_NODE' undeclared (first use in this function)
MeCab.xs:44: error: (Each undeclared identifier is reported only once
MeCab.xs:44: error: for each function it appears in.)
MeCab.xs:45: error: `MECAB_UNK_NODE' undeclared (first use in this function)
MeCab.xs:46: error: `MECAB_BOS_NODE' undeclared (first use in this function)
MeCab.xs:47: error: `MECAB_EOS_NODE' undeclared (first use in this function)
MeCab.xs: In function `XS_Text__MeCab__Node_rlength':
MeCab.xs:228: error: structure has no member named `rlength'
MeCab.xs: In function `XS_Text__MeCab__Node_enext':
MeCab.xs:286: error: structure has no member named `enext'
MeCab.xs:289: error: structure has no member named `enext'
MeCab.xs: In function `XS_Text__MeCab__Node_bnext':
MeCab.xs:307: error: structure has no member named `bnext'
MeCab.xs:310: error: structure has no member named `bnext'
MeCab.xs: In function `XS_Text__MeCab__Node_rcattr':
MeCab.xs:348: error: structure has no member named `rcAttr'
MeCab.xs: In function `XS_Text__MeCab__Node_lcattr':
MeCab.xs:359: error: structure has no member named `lcAttr'
MeCab.xs: In function `XS_Text__MeCab__Node_isbest':
MeCab.xs:381: error: structure has no member named `isbest'
MeCab.xs: In function `XS_Text__MeCab__Node_alpha':
MeCab.xs:392: error: structure has no member named `alpha'
MeCab.xs: In function `XS_Text__MeCab__Node_beta':
MeCab.xs:403: error: structure has no member named `beta'
MeCab.xs: In function `XS_Text__MeCab__Node_prob':
MeCab.xs:414: error: structure has no member named `prob'
MeCab.xs: In function `XS_Text__MeCab__Node_wcost':
MeCab.xs:426: error: structure has no member named `wcost'
error building .o file from 'lib/Text/MeCab.c' at /usr/local/share/perl/5.8.4/Module/Build/Base.pm line 2534.

報告by miyagawaさん。0.80と0.90ではだいぶ内部構造に差があるらしい。これ、Build.PLからprobe_mecab.plってのを呼んで、バージョン情報をclibsに渡す事で回避することにする:

  # Build.PL
  my $result = do 'probe_mecab.pl'

probe_mecab.plはこんな感じ(あとでModule::Buildへの依存をなくす):

use strict;
use File::Spec;
use Module::Build;

# try probing in places where we expect it to be
my $mecab_config;
foreach my $path qw(/usr/bin /usr/local/bin) {
my $tmp = File::Spec->catfile($path, 'mecab-config');
if (-f $tmp && -x _) {
$mecab_config = $tmp;
last;
}
}

if (my $tmp = Module::Build->prompt("Path to mecab config? [$mecab_config]")) {
$mecab_config = $tmp;
}

if (!-f $mecab_config || ! -x _) {
print STDERR "Can't proceed without mecab-config. Aborting...\n";
exit 1;
}

my $version = `$mecab_config --version`;
chomp $version;
print "detected mecab version $version\n";
if ($version < 0.90) {
print " + mecab version < 0.90 doesn't contain some of the features\n",
" + that are available in Text::MeCab. Please read the documentation\n",
" + carefully before using\n";
}

my($major, $minor, $micro) = split(/\./, $version);

my $cflags = `$mecab_config --cflags`;
chomp($cflags);

$cflags .= " -DMECAB_MAJOR_VERSION=$major -DMECAB_MINOR_VERSION=$minor";
print "Using compiler flags '$cflags'...\n";

my $libs = `$mecab_config --libs`;
chomp($libs);
print "Using linker flags '$libs'...\n";

return { cflags => $cflags, libs => $libs };


で、実際のコンパイルするときは、こんな感じでpreprocessorレベルでコードを変更:



#if MECAB_MAJOR_VERSION > 1 || MECAB_MINOR_VERSION >= 0.90
... 0.90以降に使える機能 ...
#endif

なんかあとで細かく見るので0.03は明日あたりにリリース予定。


のんべぇ横丁



すんげディープ。通います。


Text::MeCab is now on CPAN



アップした。オプションとかはあまりテストしてないので問題あったら教えてください。


あらら。




Text::MeCab (和製ライブラリの問題?)より。私のText::MeCabは公開停止します。



おりょ、そうなんですか。両バージョンあってもいいんではないかなぁ~。俺のWindowsでテストしてないし。


今Text::MeCab::Nodeのドキュメント書いてる。


Text::MeCab (和製ライブラリの問題?)



一般的に和製のCライブラリインターフェースが気に入らない。Text::Kakasiもそうなんだけど、initializerでコマンドラインツールの引数と同じ物を渡すのが気に入らない。それのPerlラッパになると、



my $object = SomeObject->new("-O", "-i", "-o", "-Lhoge");

なんてことんいなりやがる。こんなん嫌だ!これはPerlじゃない。嫌い嫌い嫌い!ってことで昨日書いたText::MeCabなんだけど、こんなインターフェース:



my $mecab = Text::MeCab->new({
rcfile => $rcfile,
dicdir => $dicdir,
uuserdic => $userdic,
lattice_level => $lattice_level,
all_morphs => $all_morphs,
output_format_type => $output_format_type,
partial => $partial,
node_format => $node_format,
unk_format => $unk_format,
bos_format => $bos_format,
eos_format => $eos_format,
input_buffer_size => $input_buffer_soap,
allocate_sentence => $allocate_sentence,
nbest => $nbest,
theta => $theta,
});

for (my $node = $mecab->parse($text); $node; $node = $node->next) {
print $node->surface, " -> ", $node->length, "\n";
}


・・・というわけで公開してもいいような気がしてきた。ちょっと今細かいところを詰めてる。


Text::MeCab



SWIGってマジ嫌い。たかだかエクステンションをインストールするのになんでこんなヘビーなもんも一緒にインストールせにゃあかんのじゃ!!!!その度に時間食ってやってられない。色んな言語のサポートする時には便利なのはわかるけど、どちらにしろできることが限られてるし、ちゃんとしたバインディング作りたいならカスタムメイドじゃなきゃやったられないじゃん?


・・・ということと、なんかMeCabのインターフェースが気に入らないので書きました、Text::MeCab。XSです。SWIGいりません(まぁ、最近はすでにSWIGで展開してあるバージョンが配布されてるけど)。変なtie()インターフェース使いません。だから速いです;P



daisuke@beefcake Text-MeCab$ perl benchmark.pl
Rate mecab text_mecab
mecab 10.5/s -- -61%
text_mecab 27.0/s 158% --

まだアップロードしてない、また今夜か明日。


ほげ。



もう5月かぁああ


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)を出版させていただいております。できれば内容をアップデートしたいので是非皆様・・・現在の在庫処理にお力をお貸しください!><

月別アーカイブ