メニュー

関連ページリンク

トップ > unknown > unknown - 人気ブログ(Blog)検索結果詳細 (2009年1月7日 9時)

最近はてなのスーパーpre記法おかしくない?

なんか途中でコードが切れるんだ。

しかも古いエントリーの奴とかがおかしくなってる。

エントリ編集してみてみたらテキストは残ってるのでたぶんスーパーpre記法(シンタックスハイライト版だけかな?)に何かしら問題が出てる気がする・・・。




俺だけ?・・・と思ったんだけど、どうやらみんな同じ症状出てるみたい。



なんとなく時期的にはてブリニューアルしてから問題が出始めたような気もする。

作者:fbis

更新日:2008年12月15日 19時28分

このブログのホーム

はてなボトルとな。

はてラボに新サービスが。




screenshot

はてなボトル




おもしろいすね。

最初リグレトっぽい感じかなと思ったけどちょっと違うね。

匿名じゃないし相談ひとつにつき答えひとつみたいだし。

とりあえずパーマリンクとはてなスターに対応して欲しいところ。

あと配色が人によってはキツイかもね。ぼかぁ気にならないけども。

作者:fbis

更新日:2008年12月4日 17時46分

このブログのホーム

とかなんとか言ってるうちに

なんかはてラボ乱立キタ━━━━(゜∀゜)━━━━!!




screenshot

Hatena::Counting




screenshot

はてなニュース




Hatena::Countingおもしろいかも!

これ、秒まで出ると更に(・∀・)イイ!!んだけどどうだろ!?

はてなニュースは増田をニュースっぽくカテゴリ分けした感じかな?

画像も上げれるっぽいし差別化できそうかな。まだよくわからん。

なんかわくわくするね。こういうの。




追記

とりあえずこんなの作ってみたよ!

http://counting.hatelabo.jp/count/70

作者:fbis

更新日:2008年12月4日 18時12分

このブログのホーム

モジュールがMoose依存してた。別れたい…

さて毎年年末が近づくとブログ更新頻度が下がるid:fbisですが、Mooseも馴染んできたところなのでそろそろMooseに対して一言いっておくかということでね、はい。

Mooseは素晴らしい。とてもベリー素晴らしい。何より人に優しい。人間に優しい。

がっ!しかし、Mooseはまだ使うには早すぎた。ナウシカの巨神兵ばりに早すぎたんだ。

実際に組み込んでみて感じた問題点。

大きく分けて二つ。




その壱:オブジェクト生成のコスト

やはりなんといってもnewのコストが高い。遅い。

一つ一つを見ればそこそこなんだけどやはりnewのコストは高い。

Mooseを使うのであれば極力newを避けるような仕組みの中に取り入れないと微妙。Catalystで例えるならsetupの時点でnewして以後キャッシュされるような実装だ。

newさえ終わればあとは(複雑なMooseの使い方をしてない限り)それほど問題ではないように思える。

ちょっとした小さなモジュールを作るのにMooseは凄い便利。タイプ量も物凄い減るし簡素で可読性も良い。

だからなおさら小さなモジュールでもMooseを使いたくなる。するとnewの呼ばれる回数が多くなる。どんどんコストが上がっていくという寸法だ。

ぶっちゃけMooseで個人的に良く使う機能と言えばhasのdefault&lazyやtrigger、coerceだったりする。

ある意味これだけのためにMooseを使っていると言っても過言ではない。

例を示そう。以下のようなMooseで書かれた定義があるとする。


has foo => (
    is      => 'rw',
    lazy    => 1,
    default => sub {
        my $self = shift;
        return 'default';
    },
    trigger => sub {
        my $self = shift;
        $self->{foo} .= ' and trigger';
    }
);

これは初めてfooメソッドがばれたときに'default'という文字列を格納、キャッシュする処理だ。

また、fooメソッドに引数が与えられた場合にのみ既存の値に' and trigger'という文字列をくっつける処理でもある。

このような処理をPOPOで実装すると以下のようになるだろう。


sub new {
    my $proto = shift;
    my %param = ref $_[0] eq 'HASH' ? %{+shift} : @_;
    my $self  = bless \%param , ref $proto || $proto;
    
    for my $member ( qw/foo/ ) {
        $self->$member($self->{$member}) if exists $self->{$member};
    }
    
    $self;
}

sub foo {
    my $self = shift;
    
    # trigger
    if ( @_ ) {
        $self->{foo} = shift;
        $self->{foo} .= ' and trigger';
        return $self->{foo};
    }
    
    # default
    exists $self->{foo} or $self->{foo} = sub {
        return 'default';
    }->();
    
    return $self->{foo};
}

これはひどい(と思うよね?)

一体「foo」と何度書いたら気が済むんだ。いつかコピペミスやタイプミスをするだろう。

そしてnewメソッド。ここでtriggerのために専用の処理を突っ込まないといけない。barメソッドを増やした場合はここも更新しないといけないというわけだ。

このようにプレーンな状態ではtriggerやdefaultを逆に書いてしまったり、間の空間に出来心で何かしらの処理を書いてしまったりしてどんどん始めの実装者の思想が失われていき、混沌に陥るわけだ。

triggerやdefaultがきちんとわかれているMooseではそのような事態は起こらない。

また、この例では省略しているがcoerceが入ってくるともうぐちゃぐちゃになるだろう。

小さなモジュールを作る分にはこの機能だけでもあれば物凄い作業の効率化が図れると思う。しかしこの機能を使うためだけにMooseを使うにはまだ少しコストが高すぎるという結論なんだよね。




その弐:依存モジュールの敷居の高さ

Mooseは依存度が高い。まぁこれに関しては実はうちの環境ではあまり問題はない。自社でいろいろいじれる環境であれば多少依存度が高くてもごりごりインストールすればいいのだから。

しかし昨今のMENTA等の軽量フレームワークの流れの中でMoose依存を外しましたなんていう流れもあるのでそうも言ってられない。

汎用的なCPAN向きのモジュールを作るのにもMooseは適している。Class::MOPを基盤としたパッケージ管理やMoose::Role等を使ったプラグインの構築などなど。非常に作りやすい。

モジュール提供側も提供しやすいし、プラグイン作成者にも作成しやすい環境作りができる。

が、やはりその依存の高さゆえになかなか広まりにくいのも事実。

そういう環境を用意できる人にしか届かないのはあまりにも不憫。だからこその軽量フレームワークという流れもきてるんだろうとは思うけど、その流れにMooseが乗るのはまだまだ厳しいだろう。








・・・・・・・・・・という文章を書いてる途中にShikaとかいうものがあるのを知ったのでちょいとそれも調べてみたところ、Mooseのメモリ食い過ぎ!&起動時間遅すぎ!を改善したものみたい。

ただ実行速度に関しては軽くベンチったところやはりMooseの方が倍以上高速(追記:ただしXS有効にしたShikaであればMooseよりも格段に早い。詳細はこちら)なので、そういった意味では前者がボトルネックになる素のCGIな環境でMoose的な構文を使いたい場合にShikaは良さげな感じがする。

とりあえず個人的にはRoleさえも必要なくてアクセサ生成とdefault,lazy,trigger,coerce,requiredがあれば日々の小さなモジュール作成が大いに作業効率化されるのでそれに特化したモジュールでも作ってみようかしらと思う今日この頃。

しかし、Moose、Mouse、Shikaなどどんどんシンプルになっていってる流れを見ると非常におもしろい。こうやって洗練されていくのかもね。


追記

Benchmarkコード張れ( ゜Д゜)ゴルァ!!と総ツッコミを受けて追記。

話の主眼じゃなかったので必要ないかな?と思ったんだけどやっぱいるよねー。

さっきの記事のShikaのベンチのコード - Unknown::Programming

作者:fbis

更新日:2008年12月2日 16時30分

このブログのホーム

さっきの記事のShikaのベンチのコード

モジュールがMoose依存してた。別れたい… - Unknown::Programming

id:tokuhiromさんにベンチうp頼まれたんだけども超個人的なBenchmarkコードなのでそのままCodeReposにあげれるような代物でもないということもあり取り急ぎエントリとしてあげておきますので自由に変更しちゃってください。


#!/usr/local/bin/perl -w
use strict;
use warnings;

package MooseBuild;
use Moose;

has userid => (
    is => 'rw',
);

has agent  => (
    is => 'rw',
    required => 1,
);

sub BUILD {
    my $self = shift;
    $self->userid(90);
    $self->userid($self->agent->user_id ) unless $self->agent->is_non_mobile;
}

no Moose;
__PACKAGE__->meta->make_immutable;
1;

package MooseDefault;
use Moose;

has userid => (
    is      => 'rw',
    lazy    => 1,
    default => sub {
        my $self = shift;
        return $self->agent->is_non_mobile ? 90 : $self->agent->user_id;
    }
);

has agent  => (
    is       => 'rw',
    required => 1,
);

no Moose;
__PACKAGE__->meta->make_immutable;
1;

package ShikaDefault;
use Shika;

has userid => (
    is      => 'rw',
    lazy    => 1,
    default => sub {
        my $self = shift;
        return $self->agent->is_non_mobile ? 90 : $self->agent->user_id;
    }
);

has agent  => (
    is       => 'rw',
    required => 1,
);

no Shika;
1;

package ClassAccessor;
use strict;
use warnings;
use base qw/Class::Accessor::Fast/;
use Carp qw/croak/;

__PACKAGE__->mk_accessors(qw/
    userid
    agent
/);

sub new {
    my $self = shift->SUPER::new(@_);
    $self->agent or croak 'agent not found';
    $self->userid( 90 );
    $self->userid( $self->agent->user_id ) unless $self->agent->is_non_mobile;
    return $self;
}

package Popo;
sub new {
    my $class = shift;
    my $param = ref $_[0] eq 'HASH' ? shift : {@_};
    return bless $param, ref $class || $class;
}

sub agent {
    my $self = shift;
    return $self->{agent} = shift if @_;
    return $self->{agent};
}

sub userid {
    my $self = shift;
    return $self->{userid} = shift if @_;
    exists $self->{userid} || do {
        $self->{userid} = $self->agent->is_non_mobile ? 90 : $self->agent->user_id;
    };
    return $self->{userid};
}

package main;

use HTTP::MobileAgent;
my $agent = HTTP::MobileAgent->new('');

use Benchmark qw(cmpthese timethese :hireswallclock);

#    my $obj1 = MooseBuild->new( agent => $agent );
#    my $obj2 = MooseDefault->new( agent => $agent );
#    my $obj3 = ClassAccessor->new({ agent => $agent });
#    my $obj4 = Popo->new( agent => $agent );
#    my $obj5 = ShikaDefault->new( agent => $agent );

cmpthese(10000,{
    moose_build => sub {
        my $obj = MooseBuild->new( agent => $agent );
        $obj->userid;
        $obj->userid('hoge');
    },
    moose_default    => sub {
        my $obj = MooseDefault->new( agent => $agent );
        $obj->userid;
        $obj->userid('hoge');
    },
    shika_default    => sub {
        my $obj = ShikaDefault->new( agent => $agent );
        $obj->userid;
        $obj->userid('hoge');
    },
    class_accessor    => sub {
        my $obj = ClassAccessor->new({ agent => $agent });
        $obj->userid;
        $obj->userid('hoge');
    },
    popo    => sub {
        my $obj = Popo->new( agent => $agent );
        $obj->userid;
        $obj->userid('hoge');
    },
});

HTTP::MobileAgent使ってたり若干ノイズがありますがご愛嬌を・・・。一応細かい違いはあれど同じような挙動をするように実装してます。

実行結果は


                  Rate shika_default moose_default class_accessor moose_build popo
shika_default  15152/s            --          -55%           -65%        -65% -83%
moose_default  33333/s          120%            --           -23%        -23% -63%
class_accessor 43478/s          187%           30%             --          0% -52%
moose_build    43478/s          187%           30%             0%          -- -52%
popo           90909/s          500%          173%           109%        109%   --

# ↓はWindows環境
                   Rate shika_default moose_default class_accessor moose_build popo
shika_default   25641/s            --          -48%           -52%        -56% -76%
moose_default   49261/s           92%            --            -7%        -15% -54%
class_accessor  53191/s          107%            8%             --         -9% -51%
moose_build     58140/s          127%           18%             9%          -- -46%
popo           107527/s          319%          118%           102%         85%   --


何かミスってたら突っ込みよろです。では。

ちなみにMooseのバージョンは0.60です。


追記

svn HEAD でとるとこうなりますね。XS を有効にするのがポイントです。gfx++


                  Rate moose_default moose_build class_accessor shika_default popo
moose_default  37037/s            --        -19%           -22%          -30% -59%
moose_build    45455/s           23%          --            -5%          -14% -50%
class_accessor 47619/s           29%          5%             --          -10% -48%
shika_default  52632/s           42%         16%            11%            -- -42%
popo           90909/s          145%        100%            91%           73%   --

Shika is slow? - TokuLog 改めB日記

これははやい。

現状CPANに上がってるShikaはXSの部分がコメントアウトされてますね。なるほど合点です。

XS使える環境であればClass::Accessorよりもはやいのでこれはいよいよガシガシ使うのアリですね。

というかこれで元記事でMooseに抱いていた懸念点は全て払拭されたような・・・・。

クシャナの判断は正しかった。

作者:fbis

更新日:2008年12月2日 18時37分

このブログのホーム

[PHP]PHP5.3のnamespaceの区切り文字に関して

今の気持ちをはてなハイクであらわしてみました。

先に言うとなんかもう色々ごめんなさい。





PHP5.3でひとこと - はてなハイク




f:id:fbis:20081029142825p:image














f:id:fbis:20081029144201p:image














f:id:fbis:20081029145605p:image














f:id:fbis:20081029161837p:image














f:id:fbis:20081029162553p:image













勘弁して下さい(つд⊂)エーン

作者:fbis

更新日:2008年10月29日 15時8分

このブログのホーム

[Catalyst]Catalyst::Plugin::Session::State::URIと携帯端末とfragment付きリンク

C::P::Session::State::URIは便利なんだけどfragmentが付いてるリンクまでセッションIDを埋め込んでしまうので微妙。

なんでかっていうとDoCoMo等、クエリとfragmentが存在する場合、ページ内リンクにならずにページ遷移してしまうんだよね。

ちなみにfragmentってのは以下のようなものね。


<a href="#">foo</a>

動画のダウンロードとかでオブジェクトタグ使ってるとダウンロードできなくなってしまうので困った困った。

なのでfragment付いてる時はセッションIDを埋め込まないようにするモジュールを作った。


package MyApp::Session::State::MobileURI;
use strict;
use warnings;

our $VERSION = 0.01;

sub session_should_rewrite_uri {
    my ( $c, $uri_text ) = @_;

    my $uri_obj = eval { URI->new($uri_text) } || return;
    
    # ignore the url outside
    my $rel = $uri_obj->abs( $c->request->base );
    
    return unless index( $rel, $c->request->base ) == 0;

    return unless $c->session_should_rewrite_uri_mime_type($rel);

    if ( my $param = $c->config->{session}{param} )
    {    # use param style rewriting

        # 「#」がついていたらセッションIDを突っ込まない
        return if defined $uri_obj->fragment;

        # if the URI query string doesn't contain $param
        return not defined $uri_obj->query_param($param);

    } else {    # use path style rewriting

        # if the URI isn't already rewritten
        return $uri_obj->path !~ m#/-/#;

    }
}

1;

こーんなのをこしらえて


use Catalyst qw(




    Session
    +MyApp::Session::State::MobileURI
    Session::State::URI
    Session::Store::DBIC




);

のように、Session::State::URIの前に設定すればおk。

これでfragment付きの場合にセッションIDが埋め込まれなくなって問題解決なり。

まーPCでは埋め込まれてもいいという人は$c->req->mobile_agentから判定して携帯端末の時だけ外すとかカスタマイズすればいいと思いまする。

作者:fbis

更新日:2008年10月9日 12時16分

このブログのホーム

最近はてなのスーパーpre記法おかしくない?

なんか途中でコードが切れるんだ。

しかも古いエントリーの奴とかがおかしくなってる。

エントリ編集してみてみたらテキストは残ってるのでたぶんスーパーpre記法(シンタックスハイライト版だけかな?)に何かしら問題が出てる気がする・・・。




俺だけ?・・・と思ったんだけど、どうやらみんな同じ症状出てるみたい。



なんとなく時期的にはてブリニューアルしてから問題が出始めたような気もする。

作者:fbis

更新日:2008年12月15日 10時28分

このブログのホーム

はてなボトルとな。

はてラボに新サービスが。




screenshot

はてなボトル




おもしろいすね。

最初リグレトっぽい感じかなと思ったけどちょっと違うね。

匿名じゃないし相談ひとつにつき答えひとつみたいだし。

とりあえずパーマリンクとはてなスターに対応して欲しいところ。

あと配色が人によってはキツイかもね。ぼかぁ気にならないけども。

作者:fbis

更新日:2008年12月4日 8時46分

このブログのホーム

とかなんとか言ってるうちに

なんかはてラボ乱立キタ━━━━(゜∀゜)━━━━!!




screenshot

Hatena::Counting




screenshot

はてなニュース




Hatena::Countingおもしろいかも!

これ、秒まで出ると更に(・∀・)イイ!!んだけどどうだろ!?

はてなニュースは増田をニュースっぽくカテゴリ分けした感じかな?

画像も上げれるっぽいし差別化できそうかな。まだよくわからん。

なんかわくわくするね。こういうの。




追記

とりあえずこんなの作ってみたよ!

http://counting.hatelabo.jp/count/70

作者:fbis

更新日:2008年12月4日 9時12分

このブログのホーム

モジュールがMoose依存してた。別れたい…

さて毎年年末が近づくとブログ更新頻度が下がるid:fbisですが、Mooseも馴染んできたところなのでそろそろMooseに対して一言いっておくかということでね、はい。

Mooseは素晴らしい。とてもベリー素晴らしい。何より人に優しい。人間に優しい。

がっ!しかし、Mooseはまだ使うには早すぎた。ナウシカの巨神兵ばりに早すぎたんだ。

実際に組み込んでみて感じた問題点。

大きく分けて二つ。




その壱:オブジェクト生成のコスト

やはりなんといってもnewのコストが高い。遅い。

一つ一つを見ればそこそこなんだけどやはりnewのコストは高い。

Mooseを使うのであれば極力newを避けるような仕組みの中に取り入れないと微妙。Catalystで例えるならsetupの時点でnewして以後キャッシュされるような実装だ。

newさえ終わればあとは(複雑なMooseの使い方をしてない限り)それほど問題ではないように思える。

ちょっとした小さなモジュールを作るのにMooseは凄い便利。タイプ量も物凄い減るし簡素で可読性も良い。

だからなおさら小さなモジュールでもMooseを使いたくなる。するとnewの呼ばれる回数が多くなる。どんどんコストが上がっていくという寸法だ。

ぶっちゃけMooseで個人的に良く使う機能と言えばhasのdefault&lazyやtrigger、coerceだったりする。

ある意味これだけのためにMooseを使っていると言っても過言ではない。

例を示そう。以下のようなMooseで書かれた定義があるとする。


has foo => (
    is      => 'rw',
    lazy    => 1,
    default => sub {
        my $self = shift;
        return 'default';
    },
    trigger => sub {
        my $self = shift;
        $self->{foo} .= ' and trigger';
    }
);

これは初めてfooメソッドがばれたときに'default'という文字列を格納、キャッシュする処理だ。

また、fooメソッドに引数が与えられた場合にのみ既存の値に' and trigger'という文字列をくっつける処理でもある。

このような処理をPOPOで実装すると以下のようになるだろう。


sub new {
    my $proto = shift;
    my %param = ref $_[0] eq 'HASH' ? %{+shift} : @_;
    my $self  = bless \%param , ref $proto || $proto;
    
    for my $member ( qw/foo/ ) {
        $self->$member($self->{$member}) if exists $self->{$member};
    }
    
    $self;
}

sub foo {
    my $self = shift;
    
    # trigger
    if ( @_ ) {
        $self->{foo} = shift;
        $self->{foo} .= ' and trigger';
        return $self->{foo};
    }
    
    # default
    exists $self->{foo} or $self->{foo} = sub {
        return 'default';
    }->();
    
    return $self->{foo};
}

これはひどい(と思うよね?)

一体「foo」と何度書いたら気が済むんだ。いつかコピペミスやタイプミスをするだろう。

そしてnewメソッド。ここでtriggerのために専用の処理を突っ込まないといけない。barメソッドを増やした場合はここも更新しないといけないというわけだ。

このようにプレーンな状態ではtriggerやdefaultを逆に書いてしまったり、間の空間に出来心で何かしらの処理を書いてしまったりしてどんどん始めの実装者の思想が失われていき、混沌に陥るわけだ。

triggerやdefaultがきちんとわかれているMooseではそのような事態は起こらない。

また、この例では省略しているがcoerceが入ってくるともうぐちゃぐちゃになるだろう。

小さなモジュールを作る分にはこの機能だけでもあれば物凄い作業の効率化が図れると思う。しかしこの機能を使うためだけにMooseを使うにはまだ少しコストが高すぎるという結論なんだよね。




その弐:依存モジュールの敷居の高さ

Mooseは依存度が高い。まぁこれに関しては実はうちの環境ではあまり問題はない。自社でいろいろいじれる環境であれば多少依存度が高くてもごりごりインストールすればいいのだから。

しかし昨今のMENTA等の軽量フレームワークの流れの中でMoose依存を外しましたなんていう流れもあるのでそうも言ってられない。

汎用的なCPAN向きのモジュールを作るのにもMooseは適している。Class::MOPを基盤としたパッケージ管理やMoose::Role等を使ったプラグインの構築などなど。非常に作りやすい。

モジュール提供側も提供しやすいし、プラグイン作成者にも作成しやすい環境作りができる。

が、やはりその依存の高さゆえになかなか広まりにくいのも事実。

そういう環境を用意できる人にしか届かないのはあまりにも不憫。だからこその軽量フレームワークという流れもきてるんだろうとは思うけど、その流れにMooseが乗るのはまだまだ厳しいだろう。








・・・・・・・・・・という文章を書いてる途中にShikaとかいうものがあるのを知ったのでちょいとそれも調べてみたところ、Mooseのメモリ食い過ぎ!&起動時間遅すぎ!を改善したものみたい。

ただ実行速度に関しては軽くベンチったところやはりMooseの方が倍以上高速(追記:ただしXS有効にしたShikaであればMooseよりも格段に早い。詳細はこちら)なので、そういった意味では前者がボトルネックになる素のCGIな環境でMoose的な構文を使いたい場合にShikaは良さげな感じがする。

とりあえず個人的にはRoleさえも必要なくてアクセサ生成とdefault,lazy,trigger,coerce,requiredがあれば日々の小さなモジュール作成が大いに作業効率化されるのでそれに特化したモジュールでも作ってみようかしらと思う今日この頃。

しかし、Moose、Mouse、Shikaなどどんどんシンプルになっていってる流れを見ると非常におもしろい。こうやって洗練されていくのかもね。


追記

Benchmarkコード張れ( ゜Д゜)ゴルァ!!と総ツッコミを受けて追記。

話の主眼じゃなかったので必要ないかな?と思ったんだけどやっぱいるよねー。

さっきの記事のShikaのベンチのコード - Unknown::Programming

作者:fbis

更新日:2008年12月2日 7時30分

このブログのホーム

さっきの記事のShikaのベンチのコード

モジュールがMoose依存してた。別れたい… - Unknown::Programming

id:tokuhiromさんにベンチうp頼まれたんだけども超個人的なBenchmarkコードなのでそのままCodeReposにあげれるような代物でもないということもあり取り急ぎエントリとしてあげておきますので自由に変更しちゃってください。


#!/usr/local/bin/perl -w
use strict;
use warnings;

package MooseBuild;
use Moose;

has userid => (
    is => 'rw',
);

has agent  => (
    is => 'rw',
    required => 1,
);

sub BUILD {
    my $self = shift;
    $self->userid(90);
    $self->userid($self->agent->user_id ) unless $self->agent->is_non_mobile;
}

no Moose;
__PACKAGE__->meta->make_immutable;
1;

package MooseDefault;
use Moose;

has userid => (
    is      => 'rw',
    lazy    => 1,
    default => sub {
        my $self = shift;
        return $self->agent->is_non_mobile ? 90 : $self->agent->user_id;
    }
);

has agent  => (
    is       => 'rw',
    required => 1,
);

no Moose;
__PACKAGE__->meta->make_immutable;
1;

package ShikaDefault;
use Shika;

has userid => (
    is      => 'rw',
    lazy    => 1,
    default => sub {
        my $self = shift;
        return $self->agent->is_non_mobile ? 90 : $self->agent->user_id;
    }
);

has agent  => (
    is       => 'rw',
    required => 1,
);

no Shika;
1;

package ClassAccessor;
use strict;
use warnings;
use base qw/Class::Accessor::Fast/;
use Carp qw/croak/;

__PACKAGE__->mk_accessors(qw/
    userid
    agent
/);

sub new {
    my $self = shift->SUPER::new(@_);
    $self->agent or croak 'agent not found';
    $self->userid( 90 );
    $self->userid( $self->agent->user_id ) unless $self->agent->is_non_mobile;
    return $self;
}

package Popo;
sub new {
    my $class = shift;
    my $param = ref $_[0] eq 'HASH' ? shift : {@_};
    return bless $param, ref $class || $class;
}

sub agent {
    my $self = shift;
    return $self->{agent} = shift if @_;
    return $self->{agent};
}

sub userid {
    my $self = shift;
    return $self->{userid} = shift if @_;
    exists $self->{userid} || do {
        $self->{userid} = $self->agent->is_non_mobile ? 90 : $self->agent->user_id;
    };
    return $self->{userid};
}

package main;

use HTTP::MobileAgent;
my $agent = HTTP::MobileAgent->new('');

use Benchmark qw(cmpthese timethese :hireswallclock);

#    my $obj1 = MooseBuild->new( agent => $agent );
#    my $obj2 = MooseDefault->new( agent => $agent );
#    my $obj3 = ClassAccessor->new({ agent => $agent });
#    my $obj4 = Popo->new( agent => $agent );
#    my $obj5 = ShikaDefault->new( agent => $agent );

cmpthese(10000,{
    moose_build => sub {
        my $obj = MooseBuild->new( agent => $agent );
        $obj->userid;
        $obj->userid('hoge');
    },
    moose_default    => sub {
        my $obj = MooseDefault->new( agent => $agent );
        $obj->userid;
        $obj->userid('hoge');
    },
    shika_default    => sub {
        my $obj = ShikaDefault->new( agent => $agent );
        $obj->userid;
        $obj->userid('hoge');
    },
    class_accessor    => sub {
        my $obj = ClassAccessor->new({ agent => $agent });
        $obj->userid;
        $obj->userid('hoge');
    },
    popo    => sub {
        my $obj = Popo->new( agent => $agent );
        $obj->userid;
        $obj->userid('hoge');
    },
});

HTTP::MobileAgent使ってたり若干ノイズがありますがご愛嬌を・・・。一応細かい違いはあれど同じような挙動をするように実装してます。

実行結果は


                  Rate shika_default moose_default class_accessor moose_build popo
shika_default  15152/s            --          -55%           -65%        -65% -83%
moose_default  33333/s          120%            --           -23%        -23% -63%
class_accessor 43478/s          187%           30%             --          0% -52%
moose_build    43478/s          187%           30%             0%          -- -52%
popo           90909/s          500%          173%           109%        109%   --

# ↓はWindows環境
                   Rate shika_default moose_default class_accessor moose_build popo
shika_default   25641/s            --          -48%           -52%        -56% -76%
moose_default   49261/s           92%            --            -7%        -15% -54%
class_accessor  53191/s          107%            8%             --         -9% -51%
moose_build     58140/s          127%           18%             9%          -- -46%
popo           107527/s          319%          118%           102%         85%   --


何かミスってたら突っ込みよろです。では。

ちなみにMooseのバージョンは0.60です。


追記

svn HEAD でとるとこうなりますね。XS を有効にするのがポイントです。gfx++


                  Rate moose_default moose_build class_accessor shika_default popo
moose_default  37037/s            --        -19%           -22%          -30% -59%
moose_build    45455/s           23%          --            -5%          -14% -50%
class_accessor 47619/s           29%          5%             --          -10% -48%
shika_default  52632/s           42%         16%            11%            -- -42%
popo           90909/s          145%        100%            91%           73%   --

Shika is slow? - TokuLog 改めB日記

これははやい。

現状CPANに上がってるShikaはXSの部分がコメントアウトされてますね。なるほど合点です。

XS使える環境であればClass::Accessorよりもはやいのでこれはいよいよガシガシ使うのアリですね。

というかこれで元記事でMooseに抱いていた懸念点は全て払拭されたような・・・・。

クシャナの判断は正しかった。

作者:fbis

更新日:2008年12月2日 9時37分

このブログのホーム

[PHP]PHP5.3のnamespaceの区切り文字に関して

今の気持ちをはてなハイクであらわしてみました。

先に言うとなんかもう色々ごめんなさい。





PHP5.3でひとこと - はてなハイク




f:id:fbis:20081029142825p:image














f:id:fbis:20081029144201p:image














f:id:fbis:20081029145605p:image














f:id:fbis:20081029161837p:image














f:id:fbis:20081029162553p:image













勘弁して下さい(つд⊂)エーン

作者:fbis

更新日:2008年10月29日 6時8分

このブログのホーム

[Catalyst]Catalyst::Plugin::Session::State::URIと携帯端末とfragment付きリンク

C::P::Session::State::URIは便利なんだけどfragmentが付いてるリンクまでセッションIDを埋め込んでしまうので微妙。

なんでかっていうとDoCoMo等、クエリとfragmentが存在する場合、ページ内リンクにならずにページ遷移してしまうんだよね。

ちなみにfragmentってのは以下のようなものね。


<a href="#">foo</a>

動画のダウンロードとかでオブジェクトタグ使ってるとダウンロードできなくなってしまうので困った困った。

なのでfragment付いてる時はセッションIDを埋め込まないようにするモジュールを作った。


package MyApp::Session::State::MobileURI;
use strict;
use warnings;

our $VERSION = 0.01;

sub session_should_rewrite_uri {
    my ( $c, $uri_text ) = @_;

    my $uri_obj = eval { URI->new($uri_text) } || return;
    
    # ignore the url outside
    my $rel = $uri_obj->abs( $c->request->base );
    
    return unless index( $rel, $c->request->base ) == 0;

    return unless $c->session_should_rewrite_uri_mime_type($rel);

    if ( my $param = $c->config->{session}{param} )
    {    # use param style rewriting

        # 「#」がついていたらセッションIDを突っ込まない
        return if defined $uri_obj->fragment;

        # if the URI query string doesn't contain $param
        return not defined $uri_obj->query_param($param);

    } else {    # use path style rewriting

        # if the URI isn't already rewritten
        return $uri_obj->path !~ m#/-/#;

    }
}

1;

こーんなのをこしらえて


use Catalyst qw(




    Session
    +MyApp::Session::State::MobileURI
    Session::State::URI
    Session::Store::DBIC




);

のように、Session::State::URIの前に設定すればおk。

これでfragment付きの場合にセッションIDが埋め込まれなくなって問題解決なり。

まーPCでは埋め込まれてもいいという人は$c->req->mobile_agentから判定して携帯端末の時だけ外すとかカスタマイズすればいいと思いまする。

作者:fbis

更新日:2008年10月9日 3時16分

このブログのホーム