2008年10月31日

Term::QRCodeっての作ってみた

QRCode大好きclouderさんがText::QRcodeを作ったのをみたnipotanさんが早速terminal化した物をgyazoにうpしてたので、gazoのコードを見ながら脳内コピペして10分くらいでTerm::QRCodeを作りました。
http://svn.coderepos.org/share/lang/perl/Term-QRCode/


ターミナルで作業してる時に、不意にQRCodeが必要になっても落ち着いてQRCodeを参照できるようになりましたね!

Text::QRCodeはCPANに上がってないけど、ネタでCPANに上げるかな

Posted by Yappo at 13:13 | Comments (1) | TrackBack

あと6人でCodeReposのコミッタが500人になる

http://coderepos.org/share/wiki/#Committersのページを見てカウントしていけば判る通り
あと6名でCodeReposのコミッターが500人になります。500人目が、どっかの偉い人とかだったらサプライズだろうなぁ。
切りがいいので、まだコミッタになってない方は今のうちどうぞ!

CodeRepos良くわかんないよ!って方は

WEB+DB PRESS Vol.47
WEB+DB PRESS Vol.47
posted with amazlet at 08.10.16
WEB+DB PRESS編集部
技術評論社
売り上げランキング: 4249
をご覧下さい。


なんか500人目の人にはkanさんがしゃぶしゃぶ奢ってくれるらしいよ!
なのできっとkanさん主催の「CodeRepos大会議」が開催されるはずです。

祇園祭見れなかったけど京都旅行良かったなぁー

Posted by Yappo at 11:42 | Comments (1) | TrackBack

2008年10月22日

Module::Collect と List::Rubyish を version++

lopnorさんからpluginファイル中に複数のpackageがあった時に、複数分取り扱えるmultipleサポートをコミットして頂いたのでModule::Collectをversion++してshipitしました。

List::Rubyishはid:hibomaにdelete_ifの挙動が逆!って突っ込みを貰って、どーしよっかと思ってたらid:naoyaにバグッてるからコード差し替えといて!と正しいコードを教えてもらってるうちにid:secondlifeが直してコミットしてくれた!一緒にrejectメソッドも追加してもらったよ!
あとid:walf443からsort_byメソッドも追加してもらって、切りがいいのでshipit!

僕は殆ど何もしてないよ!CodeReposって素晴らしいね!

Posted by Yappo at 23:23 | Comments (1) | TrackBack

2008年10月16日

CodeRepos の記事を WEB+DB PRESS Vol.47 にて書きました

CodeReposが一年経過して久しい今日この頃いかがおすごしでしょうか。

このたびTwitterでのつぶやきがきっかけで技術評論社のWEB+DB PRESSにてCodeReposの記事を書く機会を与えて頂き、今月のVol.47にて掲載される事になりましたのでご報告します。
WDP47.jpg

最新のCodeReposの動向を余す所なく伝える予定ではありますが、近々pear.coderepos.orgやらdownload.coderepos.orgやら作ると思っているので、そのへんは新しすぎて言及されてませんが、気にせずに是非ともご覧下さいませ。

個人的にはmemcachedとObjective-C 2.0がwktkであります。

どうぞご購入ください。

WEB+DB PRESS Vol.47
WEB+DB PRESS Vol.47
posted with amazlet at 08.10.16
WEB+DB PRESS編集部
技術評論社
売り上げランキング: 4249

Posted by Yappo at 02:04 | Comments (1) | TrackBack

2008年10月15日

List::Rubyish をリリースしました

ブクマコメントでnaoyaさんからhttp://github.com/naoya/list-rubylike/tree/master/lib/List/RubyLike.pmがバグも無くていい奴だから、そっちとdiffとって適用したほうがいいよ!とアドバイスいただいて、その差分をmergeしつつList::RubyListのテストコードをコピペするだけの簡単なお仕事をしてテストカバレッジ率も100%になったのでshipitしました。
というかnaoyaさん & secondlife 組の元コードのテストカバレッジ率が90%くらいだったので物凄く楽出来ました^^

http://search.cpan.org/dist/List-Rubyish/にそのうち反映されるはず。

List::RubyLike は use すると list 関数を export してくれるのですが、List:Rubyish では list 関数は export せずに new した時にリストを渡せるようにしました。

my $list = List::Rubyish->new(qw/ foo bar baz /);
が出来る。
その他 delete method の第一引数にコードリファレンス渡せます。
my $list = List::Rubyish->new(qw/ foo bar baz/);
$list->delete(sub { $_ eq 'bar' }); # bar を削除

List::RubyLike では + と >> を overload してるのですが、これを少し拡張して << を unshift に割り当てました。

他にもちょろちょろ本家から変えたりしてますが、基本的な挙動は互換性保ててるとおもいます。

Posted by Yappo at 18:29 | Comments (1) | TrackBack

2008年10月14日

List::Rubyish - hatena の DBIx::MoCo から fork した

DBIx::MoCoというhatena謹製のO/Rマッパは有名ですが、DBIx::MoCo::ListというRubyっぽいリスト操作を行ってくれるモジュールがあります。
概要はPerl のリスト操作を Ruby 風に - naoyaのはてなダイアリーが詳しいです。

DBIx::MoCo::ListはautoboxじゃないのにList::UtilやList::MoreUtilsを活用して実装してあります。
ちょっとしたリスト操作には使い勝手が良さそうなのですが、最大の欠点があります。
それはDBIx::MoCoに含まれるモジュールだという事です。DBIx::MoCoごと入れろと言われたらおしまいですが><

実はDBIx::MoCo::ListはDBIx::MoCoの他のモジュールに依存する箇所がどこにも無く簡単に切り離せるという事実があり、とあるIRCチャンネルでも単独で使いたいケースあるよね的な話が出たので、このたびList::Rubyish(命名 by lopnor++)としてforkさせました。
http://svn.coderepos.org/share/lang/perl/List-Rubyish/trunkにあります。
http://svn.coderepos.org/share/lang/perl/List-Rubyish/trunk/lib/List/Rubyish.pmhttp://search.cpan.org/src/JKONDO/DBIx-MoCo-0.18/lib/DBIx/MoCo/List.pmを見比べても驚く程同じ。
コピーしてs/DBIx::MoCo::List/List::Rubyish/gするだけの簡単なお仕事でした。
原作と違う所は map_* 系のメソッドを抜いたのとgrepメソッドでHASHリファレンスの時は$hash->{$code}するという挙動を追加したくらいです。
test codeもそのままです。

jkondさんかnaoyaさんに怒られなければこのままshipitする予定でございます。

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

Method::Signatures's benchmark

Method::SignaturesというPerlのメソッド定義や関数定義を直感的でかつ書き易く行う事が出来るcool moduleがあります。
たとえば

sub lopnor { # DBIx::Class test code style
    my($self, %args) = @_;
    $self->{danjou} = $args{danjou};
}
といったコードを
method lopnor (:$danjou) {
    $self->{danjou} = $danjou;
}
という風に書けます。いいかんじじゃないっすか?

このほどschwernによるプレゼン資料の中にM::S is 1% slowerとか書いてあったのでベンチ取ってみた。

use strict;
use warnings;

package My::Faster;

sub new {
    my($class, %args) = @_;
    bless {%args}, $class;
}
sub get { $_[0]->{$_[1]} }
sub set { $_[0]->{$_[1]} = $_[2] }

package My::Normal;

sub new {
    my($class, %args) = @_;
    bless {%args}, $class;
}
sub get {
    my($self, $key) = @_;
    $self->{$key};
}
sub set {
    my($self, $key, $val) = @_;
    return $self->{$key} = $val;
}

package My::MethodSignatures;
use Method::Signatures;

method new (%args) {
    return bless {%args}, $self;
}
method get ($key) {
    return $self->{$key};
}
method set ($key, $val) {
    return $self->{$key} = $val;
}

package main;
use Benchmark ':all';

cmpthese(
    timethese(
        50000,
        {   
            faster => sub {
                my $obj = My::Faster->new( bar => 'baz' );
                $obj->get( 'bar' );
                $obj->set( foo => 'bar' );
                $obj->get( 'foo' );
            },
            normal => sub {
                my $obj = My::Normal->new( bar => 'baz' );
                $obj->get( 'bar' );
                $obj->set( foo => 'bar' );
                $obj->get( 'foo' );
            },
            MethodSignatures => sub {
                my $obj = My::MethodSignatures->new( bar => 'baz' );
                $obj->get( 'bar' );
                $obj->set( foo => 'bar' );
                $obj->get( 'foo' );
            },
        }
    )
);
こんな感じで。
すごく意地悪な感じでfasterのコードを書いた、なんでかはYappoLogs: Perlで数有る$selfを取る手法をベンチマーク取ったを見てチョ。

平均値っぽい値の結果は下記の通り。

$ perl ./benchmark.pl 
Benchmark: timing 50000 iterations of MethodSignatures, faster, normal...
MethodSignatures:  0 wallclock secs ( 0.49 usr +  0.00 sys =  0.49 CPU) @ 102040.82/s (n=50000)
    faster:  1 wallclock secs ( 0.32 usr +  0.01 sys =  0.33 CPU) @ 151515.15/s (n=50000)
            (warning: too few iterations for a reliable count)
    normal:  0 wallclock secs ( 0.37 usr +  0.00 sys =  0.37 CPU) @ 135135.14/s (n=50000)
            (warning: too few iterations for a reliable count)
                     Rate MethodSignatures           normal           faster
MethodSignatures 102041/s               --             -24%             -33%
normal           135135/s              32%               --             -11%
faster           151515/s              48%              12%               --
激おそでは無いが許容出来そうな感じでもありますな。
まぁPODに
This is ALPHA SOFTWARE which relies on YET MORE ALPHA SOFTWARE. Use at your own risk. Features may change.
とか書いてあるから困りそうな所で使わないけど。

Posted by Yappo at 15:43 | Comments (3) | TrackBack

2008年10月02日

Module::Setup 0.02

Module::Collect 0.03のリリース大失敗してModle::Setup0.01が全く動かないのでversion++した。

Posted by Yappo at 11:43 | Comments (1) | TrackBack

2008年10月01日

Module::Setup - pmsetupをモジュール化した

Perlのモジュールをまず最初に作る時はpmsetupModule::Starterなどを使うのが一般的です。
かく言う余もpmsetupでガリガリ書いてたんですが、はこべさんやらdannさんやらの最近の記事を見て思う所もあってpmsetupをモジュール化してみました。
http://svn.coderepos.org/share/lang/perl/Module-Setup/trunk/

使い方は簡単!cpan Module::Setupでinstallして(まだCPANにあげてないよ!)

 $ module-setup Foo:Bar
を実行するだけ!
ほぼpmsetupと同等の挙動でひな形を作ってくれます。あらべんり!

これだけじゃまったく意味が無いのでModule::Setupらしい所を。。。

flavor

Module::Setup には flavor という概念があり(Module::Startっぽい)module-setupコマンドを叩く時にflavorを切り替える事で、様々なモジュールのひな形を利用出来ます。
現在はDefaultとCodeReposのflavorがあり

 $ module-setup --init --flavor-class=CodeRepos coderepos
 $ module-setup CodeRepos::Module coderepos
という操作で、codereposのflavorを作って、そのflavorをひな形にしたモジュールを作成出来ます。

flavorの編集

flavorは~/.module-setup/flavorの中にflavor別のディレクトリに入っています。
codereposなら ~/.module-setup/flavor/coderepos/template の中身がひな形として使われています。
flavorを使ってひな形を作る時には、このtemplateディレクトリの構成そのまま使われますので、自分の趣味に合うように編集したり必要なファイルとかを追加すると良いでしょう。

このflavor用の設定ファイルは ~/.module-setup/flavor/coderepos/config.yaml にあります。pluginsディレクトリがありますが、この中に適当なファイル名でModule::Setup::Pluginを継承したモジュールを書いてconfig.yamlのpluginsにmodule nameを追加しておくと、このflavorのひな形を作るときにプラグインが読み込まれます。
今の所template処理や新規作成するモジュールの情報を変更するフェーズにフック出来るけど、細かいのはModule::Setup:Plugim::*などのソースを読んで下さい。

subversion用のディレクトリやひな形作成後のperl Makefile.PL make make test などは全部Pluginで行っています。
ちなみに =/.module-setup/plugins には、全flavorでloadされる独自pluginを置いておけます。

flavor を packする

flavorを自分好みに編集したらsvnで管理するにしろtar.gzにするにしろ自由ですが--packオプションでflavorの中身全てを一つのpmファイルにしてくれます。

 $ module-setup --pack MyCodeRepos coderepos > MyCodeRepos.pm
これで作られたファイルを配布するなり好きにすれば良いでしょう。
flavorにするには
 $ module-setup --init --flavor-class=+MyCodeRepos myrepos
とかで出来ます。

packされたflavorを直接使ってひな形つくる

いま作った MyCodeRepos.pm を module-setup --init しないでも直接使う事が出来ます。

 $ module-setup --direct --flavor-class=+MyCodeRepos myrepos
~/.module-setup の変わりに File::Temp で作ったテンポラリディレクトリの中に flavor を展開しているだけです。

おわりに

--pack やら --direct を上手く活用すると catalyst.pl でやってくれるようなヘルパーアプリを作れます。
Module::Setup->run の $options と $argv に適切な値を渡せば、他のモジュールから叩けるはず。
例えばflavor template の lib/____var-module_path-var____.pm の ____var-module_path-var____ は 実際の module の path に書き換えられるので、フレームワークのモジュール追加のヘルパーアプリとかに応用できる。

既存の物とは違ってひな形の元ファイルを、普通のファイル操作で編集出来るって所が便利なんじゃないのかなぁと思ってる所。(Module::Starter::Plugin::CGIApp も似たアプローチだけどキモイというか、Module::Sterter::PBP的だ)
ひとしきり固まれば pack して、自作アプリに組み込んだりも出来るから便利そうだなぁと。

以前からpmsetupをモジュール化するという話は出ていたのですが、「そこまでやるならModule::Sterter使うだろJK」やら「一枚岩のスクリプトで気が変わったらスクリプトを書き換えればひな形が変えられるのがpmsetupの良い所!」という感じで誰も手を付けませんでした。
もちろん僕もそう思っていたのですが、若干必要に迫られた感もあってModuler::Sterterに手を出してみようと思ったら、すこぶるめんどくさくなったのでModule::Setupを作ったのでした。

たぶん他の人のpmsetupも全部カバーできそうかも?

Posted by Yappo at 18:21 | Comments (3) | TrackBack