2013年05月23日

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 (0) | Perl

2013年05月15日

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 (0) | Perl

2013年05月09日

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 (0) | Perl

2013年04月25日

月曜日の悪魔こと yappo です。
今時のグローバルな社会ではみなさん多言語対応の web アプリを書いているとおもいますが、その時に使う Accept-Language を解析してくれるのを書きました。

HTTP::AcceptLanguage

Plack なアプリだったら。

my $lang = HTTP::AcceptLanguage->new($req->header('Accept-Language'))->match(qw/ en fr es ja zh-tw /);
ってするだけで、英語フランス語スペイン語日本語台湾語の中からユーザが利用可能な最適な言語を探して返してくれます。

もし適切な言語が無ければ undef を返すので、あなたがおすすめの言語で返しておくといいでしょう。

I18N::AcceptLanguage っていうのが既にあるんですが、名前空間がわかりづらいのと、ドキュメントがわかりづらいのと、コードが余計な事やってるのと、インデントが独自すぎてコード読めないのと、頑張ってコード読むとバグがあったり解釈がRFCの通りになってなかったりして、ハマった時のデバッグが不能だったので作りました。

まぁ、 RFC の件はあんまどうでもいい。っていうか RFC なんか信じてたら世界が破滅するので厳密な実装にはなってなくて、あるていど実用的にしてあります。

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

2013年04月01日

こんにちわ!
先週金曜日に NHN で開催された PerlCasual っていうイベントで Perl の例外処理最新ベストプラクティスの話をして来ました。

http://yappo.github.com/talks/20130329-perlcasual7-exception/

yusukebe が開催するよって言うから、話したいって言ったら「もうスピーカーきめちゃった!」とか言われてたんですが、カジュアルに仲間に入れてもらえました。

スピリチュアルな話とかぼうよくわからないんで感想とか書けないんですが、yusukebeさん駄目な人間さん、NHNさんありがとうございました!

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

2013年03月26日

最近 Perlの話題を日本語で – Lingr という革新性力が活発ですが、やっぱり lingr は情報密度が薄いから、情報密度が濃い irc client から使いたいっていう事で1週遅れで導入しました。

材料

  • Perl(筆者はCentOSに最初から入ってる5.8.8を使っています)
  • Carton(適当に入れてください、筆者は sudo cpan Carton で入れました)
  • git

入れ方

  1. git clone git://github.com/tokuhirom/lingr-ircd.git
  2. cd lingr-ircd (5.8.8 標準の Scalar::Util が Mouse で動かんから cpanfile に requires 'Scalar::Util' => '1.27'; っての追加した)
  3. carton install
  4. Developer CenterのYour Appsのregister a new appで適当にアプリ登録
  5. carton exec -- perl ./bin/lingr-ircd --ircd_host=127.0.0.1 --ircd_port=[好きな奴] --lingr_user=[lingr のユーザ名] --lingr_password=[lingr のパスワード] --lingr_api_key=[Your Apps の key 列]
  6. 移動すると入ってるチャンネル名一覧が出るから、起動した irc server につないで /join #perl_jp とかすればいい
  7. なんかユーザ一覧取れないけど、待ってればだれか発言するし、挨拶でもすれば帰ってくるから接続テスト完了する

happy lingr life !

Posted by Yappo at 15:48 | Comments (0) | TrackBack (0) | Perl

2013年03月13日

perlbrew には

$ perlbrew upgrade-perl
というのが実装されてるのがあまりにも有名ですが、これは現在使ってる環境の perl を、そのマイナーバージョンの中で一番新しいバージョンにアップグレードしてくれるんです。
perl-5.16.1 を使っていたら perl-5.16.3 に perl-5.14.2 を使っていたら perl-5.14.4 に。という具合ですね。
同じマイナーバージョンの Perl では XS バイナリの互換性とか保証されているので、すでにインストールされているモジュールはそのまま利用できる状態になっています。

だがしかし

$ perlbrew install perl-5.16.2
して作った環境を upgrade-perl すると 5.16.3 が入ってるのに perl-5.16.2 って名前がついたままでキモい!
実際には(c)tokuhirom みたいになってて、どのバージョンかわかるんだけど perl-5.16.2 (5.16.3) とかもっときもい!

ってことで、最初に perlbrew 環境をセットアップするときは

$ perlbrew install perl-5.17.2 --as perl-5.17
みたいな感じでマイナーバージョン止まりの名前に変えておいて、 security release が出たら perlbrew upgrade-perl とかするとスマートに運用出来る事でしょう。

別のバージョンからモジュール持ってくる方法

例えば、ついでに perl-5.16 から perl-5.17 に移行したい時とかは、こうやると 5.16 で入れてたのを引き継げる。

$ perlbrew install perl-5.17
$ perlbrew switch perl-5.17
$ /Users/onapeko/perl5/perlbrew/perls/perl-5.16/bin/perl -MExtUtils::Installed -E 'say($_) for ExtUtils::Installed->new->modules' | cpanm

追記

もっと良い事を教えてもらった。

$ perlbrew use perl-5.16
$ perlbrew list-modules | perlbrew exec --with perl-5.17 cpanm
ってやるのが一番簡単に perl-5.16 のモジュールを 5.17 に入れられる。 help の一番最後に書いてあった!

参考文献: Upgrade in Place with Perlbrew
安定的な Perl アプリケーション運用のための perlbrew 運用テクニック - tokuhirom's blog. blog.64p.org

Posted by Yappo at 15:21 | Comments (0) | TrackBack (0) | Perl

perlbrew best practice まとめようと思ったら perlbrew lib なるコマンド見つけたので使ってみた。
なんか、一度ビルドした perl binary と元の site_perl を使いまわして、新たに lib path だけ変えて複数の環境を手軽に切り替える事が出来るってやつみたい。

例えば perl-5.17 の環境に @suneo って lib を作ると、 perl-5.17 の通常のライブラリパスに追加されて @suneo のライブラリパスが利用できる。そして cpanm で install するときは @suneo を汚さない。という branch っぽい作業するときに便利そう。

作る

$ perlbrew lib create suneo
ってコマンドで suneo っていうのができます。 perlbrew list してみると
 $ perlbrew list
  perl-5.14.1
  perl-5.15.2
  perl-5.16.0
  perl-5.16.1
* perl-5.17 (5.17.2)
  perl-5.17@suneo
  perl-5.17.2
  perl-5.17.5
みたいになっります。
$ perlbrew lib create perl-5.17@suneo
って感じでフルで指定もできますね。

使う

普通に

$ perlbrew use perl-5.17@suneo
ってするだけです。

lib path を見るとこんな感じ。

$ perl -E 'say join "\n", @INC'
/Users/onasui/.perlbrew/libs/perl-5.17@suneo/lib/perl5/darwin-2level
/Users/onasui/.perlbrew/libs/perl-5.17@suneo/lib/perl5
/Users/onasui/perl5/perlbrew/perls/perl-5.17/lib/site_perl/5.17.2/darwin-2level
/Users/onasui/perl5/perlbrew/perls/perl-5.17/lib/site_perl/5.17.2
/Users/onasui/perl5/perlbrew/perls/perl-5.17/lib/5.17.2/darwin-2level
/Users/onasui/perl5/perlbrew/perls/perl-5.17/lib/5.17.2
.

cpanm

普通にいれれます。

$ cpanm -v Acme::Acotie
...
OK
Successfully installed Acme-Acotie-0.02
Installing /Users/onasui/.perlbrew/libs/perl-5.17@suneo/lib/perl5/darwin-2level/.meta/Acme-Acotie-0.02/install.json
Installing /Users/onasui/.perlbrew/libs/perl-5.17@suneo/lib/perl5/darwin-2level/.meta/Acme-Acotie-0.02/MYMETA.json
3 distributions installed
という感じで普段と違うところに入ります。

へんなとこ

最新の App::perlbrew/0.59 だと use perl-5.17@suneo したら use perl-5.17 できなくなっちゃって、一度ターミナル落とさないと use できなくなって頭がふっとーしそーだおぉ。

まとめ

最近は carton 使ってるから、俺は使うかどうかわからない。

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

2013年03月12日

見た目があれだなーと思ってたところに、ひろむせんせいが css をあててくれました!
やったね!

https://metacpan.org/release/YAPPO/App-Ikachan-0.11/

Posted by Yappo at 13:48 | Comments (0) | TrackBack (0) | Perl

2013年03月08日

App::Ikachan 0.10 でました。

3つの新機能が追加です

大量のチャンネルに JOIN した状態で Excess Flood された後にサーバに繋ぎ直して元居たチャンネルに入り直そうとする時に
短期間で JOIN しまくるので、 JOIN だけで Excess Flood されてまたサーバからキックされてしまう無限ループしてしまう酷い状況だったのですが sleep しながら JOIN するように AnySan の方で変えたので、この不具合が解消された予定です。

cpanfile で依存モジュール管理するようになったので、 carton で依存モジュールの管理が可能になりました。

ふしはらかん画伯による、とっても可愛いロゴ画像が搭載されました!
どのようなロゴかは是非アップデートしてお試し下さい!

Posted by Yappo at 13:42 | Comments (0) | TrackBack (0) | Perl

2013年03月07日

Perl で L10N するにはhttp://blog.64p.org/entry/20110224/1298521852こういうことするんですが、今時はTTなんかつかわない!Xslateだ!ってことで Locale::Maketext::Extract::Plugin::TT 使ってたんですが、いろいろ怪しいのでちゃんとしたの作ったよ!

https://metacpan.org/release/Locale-Maketext-Extract-Plugin-Xslate

他のプラグインとちょっとだけオプション変わっちゃうけど、 start_tag とか変えるのも対応できるし syntax も全部対応できるよ。

Text::Xslate の AST とる internal な API 使ってるけど、 gfx に話して internal 扱いやめてもらうことになったので、安心してご利用いただけます。


非建設的な DIS や FUD が万円している昨今ではございますが、中の人達は非常に建設的ですね。

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

2013年03月04日

cpanm / carton の新しいバージョンも出たことだし、そろそろみんなの carton の知見を集めましょうってことで Carton Conference を開催して来ました。

当日の模様は動画では無くはやりの podcast で配信します。
Podcast SP1: 2013/03/02 Carton Conference Tokyo 2013 / riywo's Podcast

carton 業界の今までとこれからをが見える貴重な音声ですので皆さん、どうぞご利用ください。
僕の死霊はhttp://yappo.github.com/talks/20130227-cartoncon/です。

podcast してくれた riywo さんと、会場提供やら準備をして頂いたLINE(仮)さんと中野人に感謝です。

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

2013年02月28日

―― Perlの女神さんはブログでPerlのソースコードを公開してますけど、プログラミングはいつ覚えたんですか?
―― それまではプログラミングは全然経験なし?
―― WiiRemoteって、マウスを使わないでプレゼン資料を操作するデバイスですよね。ダイエットなんかもできる。
―― 鮮魚を喰らう……鮮魚を。
―― ところで、なぜ「鮮魚」の研究を始めたんですか?
(中略)
―― Perl女神さんはWebアプリを開発できますし、ハードウェアとの連携も経験している。後はサーバーでも覚えたら完璧なエンジニアですね。
―― では、すっかりエンジニアのPerl女神さんから、読者のエンジニアに何かメッセージを。

そんなPerl女神さんのインタビュー全編はこちら

Posted by Yappo at 17:46 | Comments (0) | TrackBack (0) | 適当