というわけで、このところ毎日やってる勝手に添削のコーナー。今回はDMAKI版Text::MeCab。

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

今回のソースは、たったこれだけ。

Text-MeCab-0.02/lib/Text/MeCab.pm
package Text::MeCab;
use strict;
use vars qw($VERSION @ISA %EXPORT_TAGS @EXPORT_OK);
BEGIN
{
    $VERSION = '0.02';
    if ($] > 5.006) {
        require XSLoader;
        XSLoader::load(__PACKAGE__, $VERSION);
    } else {
        require DynaLoader;
        @ISA = qw(DynaLoader);
        __PACKAGE__->bootstrap;
    }

    require Exporter;
    push @ISA, 'Exporter';

    %EXPORT_TAGS = (all => [ qw(MECAB_NOR_NODE MECAB_UNK_NODE MECAB_BOS_NODE MECAB_EOS_NODE) ]);
    @EXPORT_OK = map { @$_ } values %EXPORT_TAGS;
}

sub new
{
    my $class = shift;
    return (ref($_[0]) eq 'HASH') ? $class->_new(@_) : $class->_new_optarg(\@_);
}

1;

Text::MeCab::Nodeに至っては、PODしかありません。

え?そんあ馬鹿な、と思っているあなた。それが自然です。parse()の定義はどこ?Text::MeCab::Nodeはどこ?、実はここにあるのです。XSの世界へようこそ。

Perlのコードもそうですが、XSのSourceも実にきれい。PODの英語まで申し分なさげ。うーん、Advanced Perl Programmerの鏡ですねえ....といいたいところですがちょっと待って。

はっきり言ってXSに詰め込み過ぎです。

たとえば、これだと新機能を追加したり、ちょっとしたbugfixをするという時に、Perl側でできなくなっちゃいます。また、XSを読み書きできる人はPerlを読み書きできる人よりも二桁は少ないので、ツッコミビリティも多いに低下します。

たとえば、->parse()メソッドは、Perlの方でおおかた実装しておいて最後の段階でXSを呼ぶようにしておけば、事前にEncodeを使ってMeCab側の文字コードにあわせるなどといったことができるのに、XSで定義しているため、Perlであればpatchの形でもらえたかも知れない支援が、XSでは単に「うごかねー!」という突っ込みに変わってしまう可能性大です。

この「どこまでXSにすべきか、どこまでPerlのままにしておくか」という間合いは実に難しいのですが、bottomlineとして、「XSにしか出来ない部分だけXSにしとく」がおおよそのBest Practiceになります。だから->new()におけるoptionの指定などは、Perl側にふっちゃうべきで、充分に前処理しておいてから->_new()(あまりよい名前ではない。後述)を呼ぶようにすべきなのです。

私の好みは、XSによるsub/methodにはすべてxs_を頭につけて、Perl Sourceでも「ここでXSを呼んでいる」とか確実にわかるようにしておくというものです。特に同じ実装がPure Perlでも併存する場合、これは威力を発揮します。

*mysub = \&xs_mysub;

とするだけでXS版に切り替わるのですから。

しかしそれらの点を除けば、codeはすごくわかりやすく、私は逆にMeCab.xsのおかげでやっとこさきちんとMeCabのAPIを理解できました。SWIG版はもう人が読む気しませんし、makamaka版のInline::C => XS版もしかり。この辺はさすがです。

ですが、やはりPerlでも出来る、というよりPerlの方がずっと得意にしているOptionの処理までXSにしてしまうというのは、XSに驕るものXSに溺れるという感じがします。

そうそう。あと、細かいことですが、benchmark.plは、t/の中に入れておいた方がいいです。ExtUtils::MakeMakerのバージョンによっては、これもinstallしちゃう場合があるので。

Dan the XS Hacker

P.S. あと、MeCabの方に、自分はどんな文字コードを受け付けるのかを教えるAPIが見当たらないようですねえ。Make時になんとかするしかないのだろうか...

P^2.S. それにしても、XSに関しては、良書が少なく、ここにあげたAdvanced Perl Programmingですら「入門」に過ぎません。どうしてもソース嫁な世界になってはしまうのですが....充分な需要が見込まれれば私が書いてもいいのだけど....他の言語の場合も一緒にして....