2013年05月23日

while or goto

use strict;
use warnings;
use Benchmark 'cmpthese';

cmpthese( 100 => {
wile => sub {
my $i = 0;
while () {
return if $i++ == 1_000_000;
}
},
goto => sub {
my $i = 0;
LOOP:
return if $i++ == 1_000_000;
goto LOOP;
},
});

__END__

# on v5.16.3
Rate goto wile
goto 9.37/s -- -54%
wile 20.4/s 118% --

# on v5.17.2
Rate goto wile
goto 7.22/s -- -54%
wile 15.8/s 118% --

# on v5.18.0
Rate goto wile
goto 9.30/s -- -43%
wile 16.2/s 74% --

Posted by Yappo at 14:37 | Comments (0) | TrackBack

2013年05月15日

zh-hans, zh-hant に対応してない!って怒られた時は

Amon2::Plugin::L10N だと以下のように書けます。
po/zh-hant.po とか po/zh-hans.po とかは用意しとかなくていいです。きもちわるいけど。

my $LANG_RE = qr/\A(?:en|ja|zh-tw|zh-cn)\z/;
__PACKAGE__->load_plugins('L10N' => {
    default_lang          => 'en',
    accept_langs          => [qw/ en ja zh-tw zh-cn zh-hans zh-hant /],
    po_dir                => 'po',
    before_detection_hook => __PACKAGE__->is_development ? sub {
        my ($c) = @_;

        my $param_lang = $c->req->param('lang');
        if ($param_lang && $param_lang =~ $LANG_RE) {
            $c->session->set('lang', $param_lang);
            return $param_lang;
        } elsif (! defined $param_lang) {
            my $session_lang = $c->session->get('lang');
            if ($session_lang && $session_lang =~ $LANG_RE) {
                return $session_lang;
            }
        }
        $c->session->set('lang', '');
        return;
    } : undef,
    after_detection_hook  => sub {
        my($c, $lang) = @_;
        return 'zh-tw' if $lang eq 'zh-hans';
        return 'zh-cn' if $lang eq 'zh-hant';
        return $lang;
    },
});
Posted by Yappo at 20:45 | Comments (0) | TrackBack

2013年05月09日

Amon2 で国際化アプリを簡単に書く Amon2::Plugin::L10N を出しました

Perl で L10N する方法としてはPerl でつくった web サイトを L10N する方法 - tokuhirom's blog.が有名ですが、昨今はうっかりパンケーキとか唐揚げを食べてたらロンドンとかに海外進出しちゃうようなのが当たり前になった現代においては、 blog のコードをコピペするやつは死んどけば良いので、死なないため殺されない為に実用的に CPANize して殺す側に回りました。

https://metacpan.org/release/Amon2-Plugin-L10N/(現在の最新版は v0.1.3 です。)

貴方のプロジェクトのベースクラス、例えば Amazlet.pm などの中に以下のコードを埋め込みます。

__PACKAGE__->load_plugins('L10N' => {
    accept_langs => [qw/ en ja zh-tw zh-cn fr /],
});

その後 xslate の function として以下のような関数を登録するのです。

sub l {
    my $string = shift;
    my @args = map { Text::Xslate::html_escape($_) } @_; # escape arguments
    Text::Xslate::mark_raw( Amazlet-> context-> loc($string, @args) );
}

そうすると temp/index.tt などの中に [% l('hello! amazlet world!') %] などと書けるようになります。

po/ja.po とかが適切な感じで入っていれば 'hello! amazlet world! が適切な言語の物に変換されて表示されます。

po ファイル管理だるい

自前で ja.po とか作るのだるいので簡単なスクリプト添付してあります。ただ、スクリプトを動かす為のモジュールは標準でインストールされないので

$ cpanm --width-suggests Amon2::Plugin::L10N
とやって入れてから
$ amon2-xgettext.pl en ja zh-tw zh-cn fr 
ってすれば lib や tmpl 以下の中から適切に探して作ってくれます。

まとめ

Amon2::Plugin::L10N を使ってみんなで国際化して変化でガラパゴスしましょう。詳細は pod 見ると良いです。

Posted by Yappo at 17:38 | Comments (0) | TrackBack