mixiで会社のコミュニティを作ってみた。そして最初の書き込みが麻雀大会のお知らせ。なんだ、この会社。
mixiで会社のコミュニティを作ってみた。そして最初の書き込みが麻雀大会のお知らせ。なんだ、この会社。
従姉妹がなんか送ってくれたー。イチジクとかも入ってる!わーい。
ハテナオヤさんのはてブでみた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
});
逃避とか色々かねて、以前より懸案だった「モニター、キーボード、マウスのついていない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
SCRIPTmy $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 のリザーブ。これはうまい。葉巻の味がちょっと唇に残り、甘くてうっとり。
帰りに亀屋がしまっててちょっと残念。モルトがらみのビジネスしたいなぁ。
潮時かと思いますよ!そろそろ引くデス。いい感じだったけどね。
Perl Jamの新譜ビデオがグーグルビデオにあったと。これ、久しぶりにいい感じの曲だなー。弾きたい、弾きたい。
書いたのに消しちゃったよ。
Data::FormValidator使って、多分初めて(!)「まとも」なフォームを書いた。いやぁ、意外と面倒くさいな。コマンドラインツールのほうが好きだ、俺(笑)
ともあれ、これでデータを流し込む作業開始できる。次は流し込むバイト探し。ついでにプログラムもかけるいいバイトいねぇかなぁ。
サジェスチョンがあったので"require"というパラメターを実装した。動的に生成されたモジュールに対しての実ファイルがあった場合にrequireするというもの。以前Module::Pluggableで俺がやったのと基本的には一緒。ただし、今回実装したのは動的に生成されたモジュールに対してのみ。俺の以前書いたヤツはあるネームスペースに存在するものを全てrequireする。
バイト探し関連で飯食って1時過ぎに家に帰ったのだけど、今4:59。あ、あれ・・・
ざばざば。先週はプールが清掃中とかでいけなかった。今日はゆっくり目にざばざばと。やっぱここのプール人が少なくていいわ・・・
帰り際にメールが来て(多分特に用無し状態においては初めて)ちと会話。すげぇ舞い上がったのだが、やっぱり何回考えても「これって・・・高校生状態だよな・・・」と自分の挙動を反省。
俺の作ったマグロの煮付けがうますぎる。本当にうまい。く、今日は日本酒がない・・・
渋谷→南青山→皇居→虎ノ門→麻布→広尾→渋谷と、サイクリングでぐるぐる。楽しかったが、皇居に行く前の山王坂でなんかバテてしまってた。皇居外苑でぼーっと休んだりしつつ。途中ビックカメラでパーフェクトグレードZガンダムのプラモ買いそうになってやばかった。1万4000円超って・・・お昼は有楽町の「タベタ」でタイ料理、630円。
帰りに日比谷公園でアフリカンフェスタやってた。でもオーガナイザーがあまりうまくないと見えて混み過ぎ。駄目駄目。
渋谷でモッツァレラ・ディ・ブッファーラ、ホタテ、マカロニサラダを購入。エビス飲みつつモッツァレラ。うまー。マグロの血合いが100円くらいで大量に売ってたので生姜で甘辛くにつつビール。ホタテ。うま。
あとは高菜の漬け物を買ってあるのだが、これは高菜、小松菜、豚肉で炒め物を作ろうと思っている。今日できなかったら明日の夕飯。
Xangoで見てたエラー、絶対これだ
2006-05-09 06:11:06 (r58) by woggle
t/51_reiss_reuse.t A; Client-Keepalive.pm MFix 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杯(このためだけにロック)。あとはラガブーリン、ラガブーリン、ラガブーリン。
http://www.mysql-partners-jp.biz/techinfo/tech_01.html
後で読む。確かjcode MLで~の変換についても誰かが話してた。実際の挙動はどうなのだろう。後でまた良く読んでから考えるけど、問題はこのエンコーディングが追加された事で実際にはどうコード書けばいいのか、ってことかな。
ちなみに(コレ書くと弾さんがすごい喜びそうだけど(笑))Encode::GuessやEncode::Detectを使って色々ホゲホゲしてるとJcodeが一番信用できるという結果に俺は落ち着いてる。例えば「傳田」という言葉をEncode::GuessとEncode::Detectで使ってみたら化け化けらった。Jcodeだとばっちり。
なんなんだと思ったけど、よくよく考えるとEncode::*のほうはあくまでも全てのエンコーディングに対応するけどJcodeのほうは日本語に特化してるから判別もできるんだろうなぁ。
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サポートが・・・
わほ。やったー、と思ってたら
なんじゃこりゃ。まぁいいけど・・・。相棒ちゃんが調べてくれたところ:
収容人員 13,753名
スタンド席9,079名/ロイヤルボックス88名/アリーナ席4,586名
http://www.naash.go.jp/yoyogi/ichitai_sisetu.html
との事なので、俺の番号は相当後のほう。う~ん。
久しぶりにテレビ見た。あいのり、キラキラアフロ、くりぃむ、浜ちゃんと。もうあいのりは誰が誰なのかわからん。
今日はちょっと堅い格好をする必要があったのでスーツ。似非サラリーマン、っつーかほぼコスプレ状態。
Data::FormValidatorに手を出してみた。結構いい感じ。FormValidator::SimpleがLyo Katoさんの手によって出てるのは気づいたが、とりあえずD::FM使おうと思ったので先ほどData::FormValidator::Constraints::Japaneseをアップしてみた。
親の誕生日も近かったし今日は家族サービスで半日潰す予定
・・・結局来ました。雨のわりに意外と盛況。晴れてたらもっとビールがうまいのになー
タイフードフェスティバルどうしようかな。
「ドッジボール」見た。バカらしすぎる。おもろ。「THE ISLAND」みた。なんだ、このオチ。
もう自分で爆笑。
1年半ぶりくらいにプール行ってきた。渋谷区民ってリッチだな、と思わせる立派な施設が誰が使っても400円。しかも人がいない!空いてる!わーい。ざばざば泳いで1時間くらい。でも1キロも泳げなかった。とほほ。
帰り道に途中にあるお店でお弁当、530円。
ワンピ素敵。
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と変わらないのだが、まぁとりあえずそこはご愛嬌。このコードだけでは何もわからないけど、
というのが目標。
えーと。まぁ混乱してたから配達が10日遅れたのは許しましょう。ですが。
えーと。クレーマーになります、ええ。
ちょっと使えると思ったのでとりあえず書いておいた。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でのフィードはエンコーディングが駄目駄目なのが多すぎる。おまいらちゃんと直せよ。
そういうわけでXMLパーサーにかけるのがあほらしい。こんな時はLWP::UserAgentと正規表現
だ。というわけでスクリプト群を作成中。yahoo! ブログの更新大杉。
あるデータベース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:
あまり重要じゃないTODO:
しかし、タクシーの中でタイプしてると車酔いがすごいな。
日本古来の物は大切にしようと常々思っている訳ですが、これだけはいただけません:和式便所。今回旅行に行ったところが和式便所だったため偉い苦労した。こんなところでは集中+リラックスして用が足せないではないか!
俺がちゃんとした使い方を知らないだけか?
数年前の事で未だに後悔してる事があって、それは今でも新しいエントリーを読むたびに後悔してる。まぁいいんだけど。
眠い。眠いよ。
カレー食ってたらズームインスーパーのクルーが来て取材してた。絶対こっちにこないと思ったのだけど、しっかり感想を聞かれましたよ。とはいえ、メインはカレーうどんだったらしく、俺は食べた事なかったので多分使われないだろうw
昨日の午後に電話があったのですが、移動中であったため早々に切った。そしたら今朝また電話がかかってきて、どうやら明日配送の模様。
22:50分くらいに帰宅。いやー、疲れた。さて仕事。
今回はネット接続を期待できなかったのでPC持って来てない。48時間近くもネットとPCがないなんて多分10年ぶりくらいじゃなかろうか。
正直 つ ら い
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みたいな物をつけたい。
当初のゴールとしては:
って事で、その後必要に応じて中身をCにするなりなんなりしていけばいいと思うのだが、どうだろう。一緒にやる人いるかなぁ?
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時間でおいらはおでかけするのですが、寝れません。5時に起きるのに3時近くまで酒飲んで遊んでるなよ、という噂もある。
http://search.cpan.org/~dmaki/Text-MeCab-0.05/lib/Text/MeCab.pm
ようやくdebian (libmecab-devがいまだに0.80)でマトモにテストしたので、id:charsbarさんの要望もあり0.02からいきなり0.05にバージョンをあげてリリース。多分このリリースで落ち着くと思います。
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ってなんか大学時代の学部サーバーのログインっぽくってイヤン。
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にアップしておきました!
俺の環境で動くだけでなくて、debianで動くようにしつつ、mocab本体をundefするとnodeが消えるところに警告くらいは入れたいのでちょいお待ちを。
どこのポ◯リスエットの宣伝だ。でも俺ってあまずっぺぇ。
0.02_03アップ。今度はprev()が抜けてたのと、テストを足したのがメインフィックス。
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";
}
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 (和製ライブラリの問題?)より。私のText::MeCabは公開停止します。
おりょ、そうなんですか。両バージョンあってもいいんではないかなぁ~。俺のWindowsでテストしてないし。
今Text::MeCab::Nodeのドキュメント書いてる。
一般的に和製の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";
}
・・・というわけで公開してもいいような気がしてきた。ちょっと今細かいところを詰めてる。
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月かぁああ
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)を出版させていただいております。できれば内容をアップデートしたいので是非皆様・・・現在の在庫処理にお力をお貸しください!><