Perlの最近のブログ記事

久々に blog 書こうとしたら、パスワード忘れて、きーーーっとなってたら ID 間違えてました。
こんばんは。

そろそろ一週間になりますが、YAPC::Asia 2011 で基調講演らしきことをしてきたので、そのお話を。


2日目_0200


今回、この話を受けた経緯としては irc で自重できない人たちの完全な悪のりに乗せられた感じですが、当日は握手会がなかったので引き受けました。

当日は、これまた自重できない人たちが何かピカピカ光る棒状の物を振ってたり、飲食禁止のはずの講堂の壇上にテキーラが一瓶置いてあったりと、とても格調高い雰囲気の前で話させていただきました。

まじめな話、今回のテーマがEvolutionということで、自分みたいなマネージャーの立場から Perl monger といかに仕事をしているかというのを紹介させてもらって、マネージャーに興味を持って裾野が広がって、Perlの仕事が増えて、みんな幸せになるんだったら、恩返しにもなるんでいいかなーと思って僭越ながら受けさせてもらった次第です。

で、何を伝えたかったかというと、牧さんが技評のインタビューでエンジニアが戦闘モードで進化するとmiyagawaさん、マネージャーモードで進化すると僕という例えをしてくれました。自分はそこまですごいマネージャーとは思ってないですが、重要なのは企業のエンジニアリングの現場には間違いなく、その両者が必要なのです。だからキャリアパスとしてマネージャーを目指すというのはありだと思うし、評価されるべきものだと思っています。

ただ、学生の人や若い人に言いたいのは若いうちは色んな経験をしてほしくて、さらにキャリアの延長線上にマネージャーというのを考えているのなら、若いうちにたくさん色々なコードを書いたり、たくさん色々なシステムを運用すべきだと思っています。それは経験となってマネージャーをやるときに必ず生きてくるわけで、逆にそういう経験をなしにマネージャーにはなれないと思います。

そして、色んな人と出会うためにも Perl、に限らなくて良いと思いますが、コミュニティにどんどん参加して欲しいと思います。YAPC の開催期間3日間で経験したと思いますが、Perl のコミュニティには仕事を超えた素晴らしい出会いがあります。そこで得られた技術や情熱、人脈はマネージャーになったときに必ず役に立ちます。自分が今回のような機会を与えられたのも Perl コミュニティでの繋がりや出会いがあったからだと思っています。若い人にはそんな機会に積極的に触れて欲しいと思います。

最後に今回も素晴らしいお祭りを準備してくれたJPAやボランティアの方々に感謝したいと思います。ありがとうございました。

I♡Perl


2日目_0226


あ、プレゼン中に紹介したのはこの本です。

Being Geek ―ギークであり続けるためのキャリア戦略
Michael Lopp
オライリージャパン
売り上げランキング: 13893

読み物としても良い本なので是非。

携帯の緊急地震速報の音が怖いので、「会いたかった」に変えるHackを募集しています。
こんばんは。

OAuth 2.0は仕組も特徴も理解していたのですが、実際に実装の必要が出てきたので今更ながら初めて使ってみました。

仕様は現在draft15というステータスで公開されています。(The OAuth 2.0 Authorization Protocol) OAuth 2.0の特徴としてはHTTPSを使って通信経路を暗号化することによりトークンを直接やりとりすることが可能となっています。そのため署名が必要なくなり、あの悪夢のような署名検証をしなくて済むようになったのが大きなメリットです。

とはいえ、読んでもよくわかんないのでコードにしてみます。Authorization ServerとResource Serverとして使ってみるのはFacebook。クライアントサイドフローとサーバーサイドフローの二つをサポートしているので、今回はサーバーサイドフローでテスト。ドキュメントはCore Concepts - Authenticationを見ました。

まずはFacebook Developersアプリの登録が必要。もちろんFacebookのアカウントも必要。

このときに忘れちゃダメなのがWeb Siteの設定でSite URLとSite Domainの指定をする必要があること。Authorization Serverからのリダイレクト先はSite Domain下のURLしか許可されないのでここが抜けてると動きません。

設定に必要なApplication IDとApplication Secretも控えておきます。

CPANにはNet::OAuth2OAuth::Lite2やそもそもFacebookであればNet::Facebook::OAuth2などがありますが、愚直に実装しないと理解できない子なので、使わないで書いてみます。こういう捨てWeb ApplicationのコードはPlackを使うととっても簡単。
内容はFacebookで認証してFacebookの友達情報を取得して表示するだけの簡単なお仕事。

短い。

フロー順に説明すると

1)
まず、何にもパラメータがない場合は、Facebook のAuthorization endpoint にユーザーをリダイレクトしてFacebookの認証を受けさせに行きます。

2)
認証が通ると、redirect_uriに指定したURLにユーザーがリダイレクトされてきます。この際にAuthorization Codeがcodeパラメータとして渡されます。

3)
このCodeを友達情報などのProtected Resourceアクセスのために使うAccess Tokenとサーバーサイドで交換します。

この際にパラメータに要求元を証明するための秘密鍵であるConsumer Secretなど本来ネットワークに流すべきではないものをつけてリクエストするのですが、このリクエストがHTTPS必須になっているので途中で改ざんされたりしないので安全であるというのがミソです。

このリクエストが成功するとAccess Tokenがレスポンスとして直接返るのですが、これもHTTPSなので安全ですよと。

4)
あとはこのAccess Tokenを利用して友達情報などを取得してユーザーに表示します。

かなりシンプルなのでライブラリが必要ないくらいです。

この次はAuthorization Server と Resources Server 側の実装検証をしてみたいなあと思います。

最近、社内で初対面の人に自己紹介すると「あ!twitterでfollowしてます。AKB好きな方ですよね?」と辱めを受けてることが多くて色々反省しています。
こんばんは。

先日、会社で新しいMac Book Airを支給されて開発環境を再構築して、せっかくの機会だったので自分の環境をメモりました。

YAPC::Asia 2010でtokuhirom氏の「モダンな Perl5 開発環境について」で大きく取り扱われたり、あちらこちらで散々エントリされていますが毎回ぐぐるのも面倒なのではっときます。

0. 下準備
gccや各種ライブラリが必要なので何はなくともXcodeをインストールします。僕はiOS SDK付きをダウンロードしてインストールしました。

ついでにhomebrewもインストールしておきます。
sudo dscl /Local/Default -append /Groups/staff GroupMembership $USER
ruby -e "$(curl -fsSL https://gist.github.com/raw/323731/install_homebrew.rb)"
wgetとかgitとかインストールしておくといいのでしておきます。
sudo brew install wget
sudo brew install git
また、bashを使ってて.bashrc派なのですが、そのままだと.bashrcが効かないのでこんな.bash_profileを作っておきます。
if [ -f ~/.bashrc ] ; then
. ~/.bashrc
fi

1. perlbrew

システムにインストールしてあるPerlは使いたくないのでperlbrewで自分用Perlをインストールします。

ダウンロードしてインストール。
curl -L http://xrl.us/perlbrew | perl - install
初期化。
~/perl5/perlbrew/bin/perlbrew init
~/.bashrcに追加。
source /Users/kimura.hideo/perl5/perlbrew/etc/bashrc
5.12.2をインストールして使用。
source .bashrc
perlbrew install perl-5.12.2
perlbrew switch perl-5.12.2

2. cpanminus

cpanは使いたくないのでcpanminusをインストールします。
curl -L http://cpanmin.us/ | perl - App::cpanminus

2. CPAN::Mini

飛行機は嫌いなのであまり乗らないけど、ローカルにCPANのミラーがあると便利なことがあるのでCPAN::Miniをインストール
cpanm CPAN::Mini
.minicpanrcに設定を書いておきます。
local:  ~/mirrors/minicpan/
remote: http://ftp.funet.fi/pub/languages/perl/CPAN/
exact_mirror: 1
ローカルミラーディレクトリを作ってミラー開始。
mkdir mirrors/cpan
minicpan
cpanmでいちいちミラー先を指定するのはめんどうなので.bashrcにエイリアスを書いておきます。
alias minicpanm='cpanm --mirror ~/mirrors/cpan --mirror-only'

4. local::lib

アプリケーションのextlibを作るときに便利なのでlocal::libをインストールしておきます。
cpanm local::lib

5. cpan-outdated

インストールされたCPANモジュールを最新に保ちたいのでcpan-outdatedをインストールします。
cpanm App::cpanoutdated
おもむろに実行。
cpan-outdated | cpanm
一応ローカルミラー用のエイリアスを,basrcに作っておきます。
alias minicpan-outdated='cpan-outdated --mirror file:///Users/hidek/mirrors/cpan | minicpanm'

6. pm-uninstall

モジュールをアンインストールしたいことがあるのでpm-uninstallをインストールしておきます。
minicpanm App::pmuninstall

あとは恒例のCPAN大会ですがTask::BeLike::Hidekとか作ってないのでCPANソムリエで有名なtokuhirom氏のTask::BeLike::Tokuhiromとか入れておくといいかも。
cpanm http://github.com/tokuhirom/task-belike-tokuhirom/tarball/master

# 2010/11/19: cpan-outdated は xargs いらないよというgfx先生の突っ込みが入ったので修正

この前、とある事情で会社で反省文を書きました。
高校生以来だったのでノスタルジックな気分に浸って反省できませんでした。
こんばんは。

というわけで、今年もYAPC::Asia に行ってきました。
今年は仕事が猛烈に忙しくてTalkはできない、LTすらもできない、前夜際は欠席、平日の1日目は懇親会から、という散々な出席状況でした。今年から土曜日も開催されてて、最初は何で休日にやるの!とか思ってたけど、まさか自分がその恩恵を受けることになるとは思いませんでした。

と、セッションはあまり出れませんでしたが、最後のキーノートで宮川さんも言ってたけど、Perlコミュニティが最高にいいところは人と人のつながりが本当に素晴らしいことで、それを思う存分味わえる場を二年目病にもかかわらず今年も開催してくれたJPAには本当に感謝したいと思います。

また、今年はHackathonをうちで開催したのですが、鍋会場を近くのちゃんこ鍋屋に外だししたこともあって、結構楽に主催できました。ただ、20人となるとちょっと手狭なので来年は庭会場をもっと整備してもっと人数を収容できるようにしたいと思います。肝心のHackathonの成果は今日、明日にも公開できたらと思います。

とにもかくにも、主催のJPAのみなさん、ボランティアのみなさん、スピーカーのみなさん、そしてすべてのPerl Hackersに感謝したいと思います。ありがとうございました!

IMG_0578.JPG

エアRTは家庭崩壊を招きかねないので絶対にしちゃだめです。
こんばんは。

そろそろモバゲーも mixi さんに続いて Yahoo! と協力して PC版 OpenSocial アプリケーションプラットフォームをリリースするそうです。というかします。

で、OpenSocial JS API では、外部のサーバーと安全に通信するための仕組みとして、Gadget Server を Proxy してリクエストする gadgets.io.makeRequest() という、メソッドが用意されています。このメソッドはオプションでリクエストに署名をつけることができて、受け手でその署名を検証することによってリクエストの妥当性を保証することができます。

これを Perl で実装する場合、詳しくは mala さんの mixiアプリのOAuth署名の検証 の記事が詳しいのですが、もうちょっと突っ込んで説明して PSGI/Plack で実装してみます。

例えばアプリケーションでGadget XMLで

function init() {
  var params = {};
  params[gadgets.io.RequestParameters.AUTHORIZATION] = gadgets.io.AuthorizationType.SIGNED;
  params[gadgets.io.RequestParameters.METHOD] = gadgets.io.MethodType.POST;
  params[gadgets.io.RequestParameters.CONTENT_TYPE] = gadgets.io.ContentType.JSON;
  params[gadgets.io.RequestParameters.POST_DATA] = gadgets.io.encodeValues({id:123456789});
  params[gadgets.io.RequestParameters.REFRESH_INTERVAL] = 0;
  gadgets.io.makeRequest("http://example.com/", function(obj) {
     console.dir(obj);
     var user = obj.data;
     alert(user.name + " loves AKB48.");
  }, params);
}

ようなことをします。

肝は

  params[gadgets.io.RequestParameters.AUTHORIZATION] = gadgets.io.AuthorizationType.SIGNED;

で、これにより Gadget Server からのリクエストに OAuth の署名がつくので、それを検証することによってリクエストの妥当性が保証できます。

受ける方のアプリケーションを PSGI/Plack で実装します。

use OAuth::Lite::ServerUtil;
use Crypt::OpenSSL::CA;
use JSON;

my $cert = <<__PUBLIC_KEY__;
-----BEGIN CERTIFICATE-----
MIICdzCCAeCgAwIBAgIJANCWpLIspxwbMA0GCSqGSIb3DQEBBQUAMDIxCzAJBgNV
BAYTAkpQMREwDwYDVQQKEwhtaXhpIEluYzEQMA4GA1UEAxMHbWl4aS5qcDAeFw0x
MDAzMjMwODE1NTlaFw0xMjAzMjIwODE1NTlaMDIxCzAJBgNVBAYTAkpQMREwDwYD
VQQKEwhtaXhpIEluYzEQMA4GA1UEAxMHbWl4aS5qcDCBnzANBgkqhkiG9w0BAQEF
AAOBjQAwgYkCgYEAtbq5Rns5IEktXldZ+37Fjlavnuc4JuwrD4F+4NQwVwVtR5yw
Vg10EanXWSGIAbUFx6hlppYOb0x/3PBMG80643LmXSJmvv4ViRUBl2Ys9Ie2L/D9
KVQXDWgJjxBGqo5MO6rA/Ip78kbiNbIQJUIJtbuJZWL3LMVe6mpIO2SUi1UCAwEA
AaOBlDCBkTAdBgNVHQ4EFgQU8bp8/6lmt5L8em6dZyoGciUUmuUwYgYDVR0jBFsw
WYAU8bp8/6lmt5L8em6dZyoGciUUmuWhNqQ0MDIxCzAJBgNVBAYTAkpQMREwDwYD
VQQKEwhtaXhpIEluYzEQMA4GA1UEAxMHbWl4aS5qcIIJANCWpLIspxwbMAwGA1Ud
EwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADgYEApalbBgXxnLJW8fM6W7E7GAE4QZbE
lvYqvtQSxwacGYoqF2FW1zrBkmTB12LTddFU01pqDaeels3Ru5TNOnTIJemFWW0D
viKtu9GqsrOye6AZR+XA5Iy/vq3EV1TCGuDNmhJaHAiLeYuLbEqmvH7/l9xNsafH
IpqnsHwF1pm0bTY=
-----END CERTIFICATE-----
__PUBLIC_KEY__

my $ca         = Crypt::OpenSSL::CA::X509->parse($cert);
my $public_key = $ca->get_public_key->to_PEM;

my $app = sub {
    my $req = Plack::Request->new(shift);

    my $util = OAuth::Lite::ServerUtil->new;
    $util->support_signature_method('RSA-SHA1');

    my $res = $util->verify_signature(
        method          => $req->method,
        url             => $req->uri,
        params          => $req->parameters,
        consumer_secret => $public_key,
    );

    my $body = encode_json({id => 12345, name => 'hidek'});
    return $res
        ? [200, ['Content-Type' => 'application/json'], [$body]]
        : [403, ['Cbntent-Type' => 'text/plain'], ['Forbidden']];
};

gadgets.io.makeRequest() のリクエストの OAuth 署名形式はその使い勝手から mixi さんもモバゲーも RSA-SHA1 で行っているので妥当性の検証は公開鍵を使って行います。検証は例によって lyokato さんの OAuth::Lite に頼るわけですが、 mala さんが指摘している通り、mixi で公開されている公開鍵はX509なのでそのまま使えないため、変換する必要があります。

後はリクエストを OAuth::Lite::ServerUtil に食わせて署名のチェックを行って、それによりレスポンスを変えます。

例では mixi さんの公開鍵を使わせてもらいましたが、もちろん公開鍵を今後公開されるモバゲーのものにかえたらそのまま動きます。

まあ、本来この辺は Middleware に含めるほうが使いかってがいいですね。

最近、咳のしすぎであばらにヒビが入りました。
大多数の人は心配をしてくださってありがたいのですが、ごく一部の極道達がおもしろ画像を連投して笑わせてくるおかげで全治が大分先になりそうです。
こんばんは。

先日、「モバイルなプラットフォームでの OAuth Signature の検証」ってエントリーを書いた際にPlack::Middlewareとかでやるべきとか書いておいて放置していたのですが、某極道が「とっとと書かないと笑わせてあばらへし折るぞ!ごるぁ!」と脅してきたのでサクッと書きました。

GitHubに置いてあります。

Plack-Middleware-Auth-OAuth

使い方は簡単。


use Plack::Builder;

 my $app = sub {
    return [200, ['Content-Type' => 'text/plain'], ['Hello World']];
 };

 $app = builder {
     enable 'Plack::Middleware::Auth::OAuth',
         'consumer_key'    => 'YOUR CONSUMER KEY',
         'consumer_secret' => 'YOUR CONSUMER SECRET';
         $app;
};

これでOAuth Signature のチェックをして失敗したら401 エラーを返すようになります。

mixi ではこのまま動きますし、モバゲー用にしたければ

 $app = builder {
     enable 'Plack::Middleware::Auth::OAuth',
         'consumer_key'    => 'YOUR CONSUMER KEY',
         'consumer_secret' => 'YOUR CONSUMER SECRET',
         'validate_post' => 1;
         $app;
};

とすれば body parameter も検証対象になるので動きます。

色々意見聞いて、もうちょっとテストとか書いたらCPANに上げます。
これで、OpenSocial のアプリが増えたら幸いです。

相変わらず、題名にセンスがありません。こんばんは。

さて、ようやくローンチしたモバゲーオープンプラットフォームですが、仕組み的にはmixiさんのモバイル版とほぼ同じアーキテクチャで Gadget Server がプロキシー的な役割をする感じになってます。

図面1

大人の事情がかなり反映された仕組みなのですが、この仕組みで非常に重要なのがGadget ServerからのリクエストをSAPがいかに信頼するかという部分です。いわゆる 2-legged OAuthでAuthorizationヘッダに含まれるOAuth Signatureの検証する部分。その部分のコードスニペットをご紹介。(mixi 用のは公開していいかどうかわかんないのでモバゲー向けだけ)

use OAuth::Lite::ServerUtil;
use OAuth::Lite::Util qw/parse_auth_header/;
use CGI;

my $consumer_secret = 'YOUR_CONSUMER_SECRET';

sub validate_signature {

    my $cgi = CGI->new;

    my ($realm, $params) = parse_auth_header($ENV{HTTP_AUTHORIZATION});

    for my $key ($cgi->url_param) {
        $params->{$key} = [$cgi->url_param($key)];
    }

    if (uc $cgi->request_method eq 'POST'
        && $cgi->content_type =~ m{^\Qapplication/x-www-form-urlencoded})
    {
        for my $key ($cgi->param) {
            $params->{$key} = [$cgi->param($key)];
        }
    }

    my $util = OAuth::Lite::ServerUtil->new(strict => 0);
    $util->support_signature_method('HMAC-SHA1');

    return $util->verify_signature(
        method          => $cgi->request_method,
        url             => $cgi->url,
        params          => $params,
        consumer_secret => $consumer_secret,
        token_secret    => $params->{oauth_token_secret},
    );
}

Apacheで動かす場合にはCGIからAuthorizationヘッダを取得することができないので mod_rewriteで

RewriteEngine on
RewriteBase /
RewriteCond %{HTTP:Authorization}  ^(.*)
RewriteRule ^(.*)$ $1 [e=HTTP_AUTHORIZATION:%1]

こんな風にしないと環境変数からは取れない。

Net::OAuthっていうモジュールもあるけど個人的にはlyokato氏謹製のOAuth::Liteの方が圧倒的に使いやすいのでこっちをつかってます。

で、このままmixiさんで動くかというと、そうでもなく両者の間には若干差があって、mixiさんは純粋な 2-legged OAuth なんだけど、モバゲーの場合は若干パラノイア的で、Gadget Server がリクエストごとに発行する Access Tokenが含まれるため、それも含めて検証する必要があります。あとPOSTの場合の挙動がちょっと違うかも。

というか、この部分って毎回検証する必要があるのだから、WAFやApplicationというよりはmod_auth_*とかPlack::Middlewareとかで何とかするレイヤーな気がしてならないので、そのうち作りたいな。

今年もPerl hackersの祭典、YAPC::Asiaが始まりました。


RIMG0383


スライドを1文字も書いていないのに前夜祭で盛大に飲んでしまい、朝何とか早起きして草稿を作って、発表の5分前まで書いて発表というとんでもない綱渡りをしましたが、何とか自分のトークは終わりました。スライドの方は後ほど公開したいと思います。

というわけで、猛烈に眠いですがここからは気楽に楽しもうと思います。

このところ、MySQL と Catalyst と 豆しば 関連のエントリをいろいろ書いていますが、それは、スケールアウト可能で、かつ、Catalystで動くアプリケーションを、今まさに作っている、という理由があるからです。

ただ、ブログエントリだとどうしても細切れになるので、一連のモジュールやプログラムを組み合わせて、どうやってスケールするウェブアプリケーションを作るのかという話を YAPC::Asia 2009 でさせていただくことにしました。

YAPC::Asia 2009 は9月10日(木)と11日(金)の2日間、東京工業大学大岡山キャンパスで開催されます。今日からチケット販売も始まったので、興味のある方はお越しいただければ、と思います。

【参考文献】

良くあるDBICのサンプルではDBIx::Class::Schema::load_classes()を使ってクラスのロードを行っています。

CD.pm
package CD;

use strict;
use warnings;

use base 'DBIx::Class::Schema';

__PACKAGE__->load_classes;
1;
load_classes()はクラスを指定しないと
CD
    Album
    Track

という構成において自動的にクラスをロードすることができます。

ここでResultSetの拡張をしたいと考えます。例えば

CD/ResultSet/Album.pm
package CD::ResultSet::Album;

use strict;
use warnings;

use base 'DBIx::Class::ResultSet';

sub search_order_title {
    my $self = shift;

    return $self->search({}, {'order_by' => 'title'});
}
1;

のようにDBIx::Class::ResultSetを継承したクラスを作ってCD::Album::resultset_class()でロードします。ここで問題になるのがこのクラスのネームスペースをどうするかという点です。

CD::ResultSet::*にしてしまうと、load_classes()でwarningが出る羽目になります。かといってload_classes(qw/Album Track/)などとクラスを指定するのもクラスが増えてきたときに大変そうです。またはResultSet::CD::AlbumのようにCDより上のネームスペー>スを使うのも、あんまりいけてない感じです。

そこでDBIC::Schemaにはもう一つクラスのロード手段としてload_namespaces()が用意されていているのこれを使います。

CD.pm
package CD;

use strict;
use warnings;

use base 'DBIx::Class::Schema';

__PACKAGE__->load_namespaces;
1;

load_namespaces()はデフォルトで

CD
    Result
        Album
        Track
    ResultSet
        Album

という構成をとります。

これのメリットはネームスペースがすっきりするだけではなく、ResutlSet::*にResutl::*と同じ名前のResutlSetクラスを作ると、Resultクラスでresutlset_class()で指定しなくても自動的にロードしてくれる点です。(ただ逆もまたしかりで、上の構成でResultSet::Hogeなどを作ると対応するResultクラスがないとwarningがでます。)

ちなみにDBIx::Class::Schema::Loaderを使ってデータベースからクラスを起こす場合は
perl -MDBIx::Class::Schema::Loader=make_schema_at,dump_to_dir:./lib -e 'make_schema_at "CD", {use_namespaces => 1, debug => 1}, ["dbi:SQLite:cd.db","",""]'
のようにuse_namespacesオプションを指定するといいです。

今回のコード

CD.pm
package CD;

use strict;
use warnings;

use base 'DBIx::Class::Schema';

__PACKAGE__->load_namespaces;
1;
CD/Result/Album
package CD::Result::Album;

use strict;
use warnings;

use base 'DBIx::Class';
__PACKAGE__->load_components(qw/Core/);
__PACKAGE__->table('album');
__PACKAGE__->add_columns(
    id => {
        data_type         => 'INTEGER',
        size              => 11,
        is_nullable       => 0,
        is_auto_increment => 1,
    },
    title => {
        data_type   => 'VARCHAR',
        size        => '255',
        is_nullable => 0,
    },
);
__PACKAGE__->set_primary_key('id');
__PACKAGE__->has_many(
    tracks => 'CD::Result::Track', 'album_id', {order_by => 'position'}
);
1;
CD/Result/Track.pm
package CD::Result::Track;

use strict;
use warnings;

use base 'DBIx::Class';
__PACKAGE__->load_components(qw/Core/);
__PACKAGE__->table('track');
__PACKAGE__->add_columns(
    id => {
        data_type         => 'INTEGER',
        size              => 11,
        is_nullable       => 0,
        is_auto_increment => 1,
    },
    album_id => {
        data_type   => 'INTEGER',
        size        => 11,
        is_nullable => 0,
    },
    position => {
        data_type   => 'TINYINT',
        size        => 1,
        is_nullable => 0,
    },
    title => {
        data_type   => 'VARCHAR',
        size        => '255',
        is_nullable => 0,
    },
);
__PACKAGE__->set_primary_key('id');
__PACKAGE__->add_unique_constraint(
    track_uq_album_id_position => [qw/album_id position/]);
__PACKAGE__->belongs_to(album => 'CD::Result::Album', 'album_id');
1;
CD/ResultSet/Album
package CD::ResultSet::Album;

use strict;
use warnings;

use base 'DBIx::Class::ResultSet';

sub search_order_title {
    my $self = shift;

    return $self->search({}, {'order_by' => 'title'});
}
1;

先日、カジュアルな飲み会の席でPerl 5.10が2007年12月19日にリリースされてから早1年半が経ったけど何か普及してなくない?って話をしてました。

そんな中、ノートのOSをUbuntu 8,04から9.04に変えてUbuntuは8.10からすでに5.10がデフォルトでインストールされてるということを知り、5.10は普及してないというのは自分の単なる思い込みかもしれないと思い、ちょっと調べることにしました。

で、見つけたのがDistroWatch.comという、300ちかいのLinux/BSDのディストリビューションの情報が紹介されているサイトで、ここからWeb::Scraperで各ディストリビューションの最新バージョンのPerlのバージョンをスクレーピングしてみました。ついでに最近見つけたChart::Clickerというモジュールでグラフを作ってみました。

結果は

foo

5.10.0124
5.8.8124
none29
5.8.76
5.8.64
5.8.03
5.8.43
5.8.93
5.8.53
5.8.21
5.9.41
5.6.11


と、5.8.8と5.10.0が同数という結果になりました。もちろんわけのわからんマイナーなディストリビューションや単なる派生ディストリビューションも含まれるのでこの情報にどこまでの意味があるかわかりませんが、なかなか面白い結果になりました。

そもそもメジャーなディストリビューションで5.10じゃないのはRHELとCentOSくらいです。(ともに6からはFedora 11ベースになるはずなので5.10になると思います。)後はDebian, Fedora, Ubuntu, openSUSE, Mandriva, Slackwareと軒並み5.10がデフォルトなので、ディストリビューションという観点からは中々の普及率と言えると思います。

後はレンタルサーバーのOSの移行がどこまで進むかにかかっていると思います。

ちなみに今回使用したコード

miyagawaさんが紹介されていたlocal::libを使って非rootでのCPAN環境を作ってみました。平たく言えばさくらインターネットのレンタルサーバで一般ユーザーでCPAN環境を作ってみました。

とはいえ、多くは先人たちの と大差ありません。

まずはlocal::libのアーカイブを取得・解凍します。最新のバージョンは1.003001です。

wget http://search.cpan.org/CPAN/authors/id/A/AP/APEIRON/local-lib-1.003001.tar.gz
tar xzvf local-lib-1.003001.tar.gz
cd local-lib-1.003001

otsuneさんの記事にある通り、BSDPANのエラーを回避する設定をします。自分はbashを使っていますが、さくらのデフォルトのcshellを使っている場合は適宜setenvなどに置き換えてください。

export PKG_DBDIR=$HOME/local/var/db/pkg
export PORT_DBDIR=$HOME/local/var/db/pkg
export INSTALL_AS_USER
export LD_LIBRARY_PATH=$HOME/local/lib
mkdir -p ~/local/var/db/pkg

local::libにはまっさらな状態からインストールすることを想定したbootstrapオプションがMakefile.PLにあり、CPANの設定もしてくれます。が、さくらのレンタルサーバにインストールされているCPANモジュールが古いのと設定がされてないため、urllistが設定されずに途中のインストールで失敗するので、CPANの設定を先に行います。

cpan
...
cpan> exit

質問に対しては基本的にデフォルトで(リターン連打) ミラーの選択だけAsia>Japanから選べばいいと思います。設定が終了したらCPANシェルを抜けます。(余談ですが、2月16日現在でcharsbarさんオススメの山形大学のミラーが2月6日付けで止まってる気がします。)

Makefileを作成します。

perl MakeFile.PL --bootstrap=$HOME/local
...

ちなみに$HOME/localを省略するとデフォルトの$HOME/perl5にインストールされます。

この時点で$HOME/local/lib/perl5以下にlocal::libが必要とするモジュールがインストールされます。

通常はこの後makeしてインストールすればよいのですが、たまにMakefileが作成されないことがあるので、その場合は先ほどのコマンドを再度実行します。

makeしてtestします。

make && make test
...
Files=2, Tests=6,  0 wallclock secs ( 0.04 cusr +  0.04 csys =  0.08 CPU)

問題なさげならmake installします。

make install

シェルの起動時に環境変数を設定するようにします。

echo 'eval $(perl -I$HOME/local/lib/perl5 -Mlocal::lib=$HOME/local)' >>~/.bashrc
cshellの場合は
echo 'perl -I$HOME/perl5/lib/perl5 -Mlocal::lib' >> ~/.cshrc

こうすることによりシェルが起動されると

export MODULEBUILDRC="/home/hidek/local/.modulebuildrc"
export PERL_MM_OPT="INSTALL_BASE=/home/hidek/local"
export PERL5LIB="/home/hidek/local/lib/perl5:/home/hidek/local/lib/perl5/i386-freebsd-64int:$PERL5LIB"
export PATH="/home/hidek/local/bin:$PATH"

という環境変数が設定されます。

後はいったんシェルを抜けるかsource ~/.bashrc(または.cshrc)してからいつものようにcpanシェルからinstall Bundle::CPANしてください。

なお、環境変数にPERL_MM_OPT="INSTALL_BASE=/home/hidek/local"が設定されているのでcpanシェルを使わずにインストールする時もperl Makefile.PL INSTALL_BASE=$HOME/libする必要なくperl Makefile.PLでよしなにしてくれます。

\mysql_enable_utf8 => 1 で DBIC::UTF8Columns 要らなくなるっぽい - 僕ト云フ事@はてな出張版

恥ずかしながら知りませんでした。
DBIx::Classの場合、DBIx::Class::UTF8Columnsを使ってutf8_columns()でUTF8フラグを立てたいカラムを指定するのですが、特定のカラムだけにUTF8フラグを立てるというのは稀で、全ての文字列のカラムに立てるのが多くの場合だと思います。
ので、DBDのレイヤーで吸収するこの方法が個人的にもベストプラクティスだと思います。
vkgtaro++

備忘でまとめておくと各DBDの接続オプションで

  • mysql: mysql_enable_utf8
  • postgresql: pg_enable_utf8
  • sqlite: unicode

に1を指定することにより、全ての文字列のカラムの値にUTF8フラグが立って返ってきます。

ちなみにmysqlのSET NAMES 'utf8'とかはサーバーに対するクライアントが使用する「文字コード」の宣言であってUTF8フラグとは直接関係ありません。

参考: Using Unicode - Catalyst::Wiki

Shibuya.pm Tech Talk #10でLTしてきました。
関係者の方々お疲れ様でした。

ニコニコ動画

題にはBenchmarkうんぬんかんぬん書いてありますが、今回自分はどっちかっていうとスピリチュアルな方向で話させてもらいました。
若干ネタに走ってしまって趣旨がぼやけましたが、はっきり言うとPHPに奪われたところを取り替えそうじゃないか。という問いかけです。
準備が足らなかったのに加えてしらふだったので、この次はアルコール注入してもっと熱く語りたいと思います。

HECon #1に行ってきたというより、コーディネートさせていただきました。
急遽決まった+SoozyConのノリで一時はどうなるかと思いましたが、皆様のご協力のおかげで無事終わることが出来ました。
この場を借りてお礼申し上げます。ありがとうございました。
また、会場整理に当たっていただいた同僚の皆様ご苦労様でした。助かりました。

で、僕は進行と懇親会の乾杯の音頭しかやってないので詳しくは

のあたりを見ていただきたいのですが、昨今のLightweight WAFs改めCGI Application FrameworksのブームなどもありHECon #2とかWAF Con #1とか言う話も出てるので、またお役に立てればと思います。

プロフィール

このアーカイブについて

このページには、過去に書かれたブログ記事のうちPerlカテゴリに属しているものが含まれています。

前のカテゴリはPCです。

最近のコンテンツはインデックスページで見られます。過去に書かれたものはアーカイブのページで見られます。