2007年08月31日

CodeRepos - 個人レポジトリを共有しよう!計画

typesterさんのつぶやき

みんながそれぞれ作って公開してる公開レポジトリを一緒くたにしちゃいたい。参加してる全員がどのファイルもみたり変更したりできるような。

パッチ送られてくる代わりに「後で見とくからコミットしといて」とかいえたりとか、つくりかけで放置したもので他の人が興味もったら続き作ってもらうとか、メンテするのめんどくなったのだれかにやってもらうとか、突発的に誰かと一緒にプロジェクト始めたりとか、できる!
に呼応する形で共有レポジトリを作りました。
http://coderepos.org/share/

特に明確な方向性とかはきまってませんし、決まるかどうかもわかりませんがtypesterさんのつぶやきを現在の方向性という事にしておきますか。
昨日作ったばかりで、今はディレクトリ構成どうしようかとかそういう事をircとかtwitterとかで話し合っているので、ディレクトリ配置が変わっちゃったりするかもですが、落ち着いてきたら配置も固定になると思います。

現在commitしてあるコードはperlの物だらけでperl専用?とかの疑問も出てましたが、どんな言語とか問わずcommitしちゃって問題ないです。
言語とかのレベルを越えて、以前流行ったdot-file公開ブームのようにdot-fileとかplaggerとかのsoftのconfigファイルの共有が出来たら面白そうです。

CodeReposに登録されてるファイルにパッチ書きたくなったり、CodeReposに自分のソースを放流したくなった方はhttp://coderepos.org/share/に記載されてる連絡先までhtpasswdで作ったファイルの中身を送って下さい。

Posted by Yappo at 19:19 | Comments (0) | TrackBack

2007年08月03日

bradとmyとuse fieldsとPseudo-hashesとHash::Utilと

bradプロダクトではuse fieldsが多用されています。そして、

my ClassName $var;
のような変数宣言が多用されています。
perldoc -f myしてみるとuse fieldsで使うみたいな事が書いてありました。
use fieldsってのは
package Jitensya;
use strict;
use warnings;
use fields qw/(sound);

sub new {
    my $proto = shift;
    my $self  = ref $proto ? $proto : fields::new($proto);
    $self;
}
1;
のようなコードがあるとして
use strict;
use warnings;
use Jitensya;

my $hatena = Jitensya->new;
$hatena->{sound} = 'わいが近藤や';
$hatena->{dog}   = 'しなもん';
という使い方をした時に、$hatena->{dog}のところでfieldsで宣言されてないからエラーが出るという物です。

で、冒頭の

my ClassName $var;
の件ですが、このuse fieldsされたpackageがuse baseとかで継承された時に役立つようです。
たとえば、以下のpackageが在る状態で
#はてなスタッフを表す
package Hatena;
use strict;
use warnings;

use fields qw(jkondo naoya kawasaki);

sub new {
  my Hatena $proto = shift;
  my $self = ref $proto ? $proto : fields::new($proto);
  $self->{jkondo}   = 'syatyou';
  $self->{naoya}    = 'CTO';
  $self->{kawasaki} = 'fukusyatyou';
  $self;
}
1;
# はてなユーザを表す
package Hatena::User;
use strict;
use warnings;
use base 'Hatena';

use fields qw(yappo);

sub new {
  my Hatena::User $proto = shift;
  my $self = $proto->SUPER::new(@_);
  $self;
}
1;
下記のコードを走らせた時はエラーもなく動きます。
use strict;
use warnings;
use Data::Dumper;

use Hatena::User;

my $jitensya = Hatena::User->new;
$jitensya->{yappo} = 'gennin';

warn Dumper $jitensya;
しかし、Hatena::Userのオブジェクトを受け取る$jitensyaの前にHatenaという指定を追加すると。。。
use strict;
use warnings;
use Data::Dumper;

use Hatena::User;

my Hatena $jitensya = Hatena::User->new;
$jitensya->{yappo} = 'gennin';

warn Dumper $jitensya;
Javaとかのtypecastみたいに、一時的に別の名前空間のfieldsにする(継承元の名前空間に固定する)みたいな事をするんだと思います。
この例では、Hatenaは、はてなスタッフだけがいるpackageなので、はてな社員でないyappoに値を入れると怒られます。

bradプロダクトで見かける

            my Perlbal::BackendHTTP $self   = shift;
            my Perlbal::HTTPHeaders $hd     = $self->{res_headers};
            my Perlbal::ClientProxy $client = $self->{client};
            my Perlbal::HTTPHeaders $rqhd   = $self->{req_headers};
のmyの後にpackage名を書くのは、こういうことからなのかなぁと。

実は、fieldsを使わなくてもハッシュのキーの制限は出来て

my $hash = [{ boofy => 1, sledge => 2 }];
$hash->{boofy}  = 'mixi';
$hash->{sledge} = 'livedoor';
$hash->{'catalyst::shanon'} = 'shanon'; # error
みたいに出来ますが、perl 5.9からは使えなくなります。
配列の一項目目ハッシュリファレンスだったら制限付きのハッシュになるそうで、これをpseudo-hash(仮想ハッシュ)と言うそうです。

perl 5.9からどうすればいいかというと、Hash::Utilを使います。

use Hash::Util;
my $hash = {};
Hash::Util::lock_keys(%$hash, qw/ boofy sledge /);
$hash->{boofy}  = 'mixi';
$hash->{sledge} = 'livedoor';
$hash->{'catalyst::shanon'} = 'shanon'; # error
と書けます。これは5.8でも使えるので、今から仮想ハッシュしたければHash::Util使えばおkっぽい。

use fieldsも5.9以降からはHash::Utilを使って実装されていますが、なぜかfields::phashが使えなくなってます、Hash::Util使えば実装出来るのになんで削除されるんだろう。

Hash::Utilの実装を見てるとInternalという名前空間の関数使いまくりなんですが、これの資料がどこにあるかが解らない。

と、つい最近知ったばっかりの仕様についてだらだら書いてみました。
応用すれば5.8環境でhash版のuse strict 'vars'もどきが書けそうですね。

Posted by Yappo at 19:56 | Comments (13) | TrackBack