2007年4月アーカイブ

Unknown::Programming - Catalyst::Plugin::FillInFormで文字が二重に化ける
でもこれ実はid:hide-Kさんも同じ名前のモジュールを作ってるみたいで(hide-k.net#blog: 使ってるCatalystのPlugins/Components)そうなるとこのモジュールCPANにあった方がいいんじゃないかとか思うんだけど。

というわけで、僭越ながら先ほどCPANにあげておきました

Catalyst::Plugin::FillInFormとpodもほとんどそのままですが、評判の悪いFormValidatorがエラーを返すと勝手にfillformする機能をオフにするオプション付き。本当はこっちの動作をデフォルトにしたいのですが、本家との挙動が変わってしまうのでやめておきました。どっちがいいんでしょうね。

そういえば今年のGWはどうなってんだろ?(この時期にこんなことを言っているってことは、予定ないことバレバレなんですが)と、ふと手帳を見て驚きました。

4月29日は「みどりの日」だと思っていたら、「昭和の日」になってるじゃありませんか。

で、慌てて調べました。

昭和の日 - Wikipedia
昭和の日(しょうわのひ)は、2007年(平成19年)から日本国の国民の祝日に加えられた祝日の名称で同日の中で最も新しい国民の祝日である。国民の祝日に関する法律(祝日法)の一部改正により追加されたもので、日付は昭和天皇の誕生日でもある4月29日、同法における定義・趣旨は「激動の日々を経て、復興を遂げた昭和の時代を顧み、国の将来に思いをいたす」となる。ゴールデンウィークを構成する日の一つである。

知らなかったです。

色々検索してたらこんなサイトも見つけました。

昭和の日 オフィシャルサイト
財団法人国民精神研修財団が事務局を勤める「昭和の日」普及委員会が運営

昭和の日ネットワーク
NPO法人「昭和の日」ネットワークが運営

どちらも怪しい。

で、ふと「みどりの日」はどーなったんだ?と調べてみると、5月4日がそうなったんですね。

みどりの日 - Wikipedia
みどりの日(みどりのひ)は、国民の祝日の一つである。日付は5月4日。1989年から2006年までは4月29日だった。国民の祝日に関する法律(祝日法)では「自然にしたしむとともにその恩恵に感謝し、豊かな心をはぐくむ」ことを趣旨としている。ゴールデンウィークを構成する日の一つである。

なるほど。

DBIx::Class::Indexer::WebService::Luceneを使ってみたいので、まずはLucene Web ServiceをCentOS 5にインストールしてみたメモ。

ちなみにLucene Web ServiceとはJavaで出来てる検索エンジンLuceneにREST APIでアクセスできるようにしたWebアプリケーションです。これにより他の言語からも使いやすくなるということ。

JDK 6のインストール

*基本的にこのエントリでやってることと同じです

ここからJDK 6u1 Download->Accept License Agreementにチェックして->Linux RPM in self-extracting fileをゲット

インストール
$ sudo ./jdk-6u1-linux-i586-rpm.bin
一応alternativeの設定
$ sudo /usr/sbin/alternatives --install /usr/bin/java java /usr/java/jdk1.6.0_01/bin/java 2
$ sudo /usr/sbin/alternatives --config java

1 プログラムがあり 'java' を提供します。

  選択       コマンド
-----------------------------------------------
*+ 1           /usr/java/jdk1.6.0_01/bin/java

Enter を押して現在の選択 [+] を保持するか、選択番号を入力します:1
後々面倒なのでシンボリックリンクを張っておく
$ ln -s /usr/java/jdk1.6.0_01 /usr/java/jdk
今回は関係ないけどクラスパスなどの設定 .bash_profile
export JAVA_HOME=/usr/java/jdk
export PATH=$PATH:$JAVA_HOME/bin
export CLASSPATH=.:$JAVA_HOME/jre/lib:$JAVA_HOME/lib:$JAVA_HOME/lib/tools.jar

apache-tomcatのインストール

ここからapche tomcat 6.0 binary tar ballをゲット 展開して配置
$ tar -xzvf apache-tomcat-6.0.10.tar.gz
$ sudo mv apache-tomcat-6.0.10 /usr/java/
$ sudo ln -s /usr/java/apache-tomcat-6.0.10 /usr/java/apache-tomcat
jsvcのコンパイル
$ cd /usr/java/apache-tomcat/bin
$ sudo tar -xzvf jsvc.tar.gz
$ cd jsvc-src
$ sudo chmod a+x configure
$ sudo ./configure --with-java=/usr/java/jdk
$ sudo make
$ ls -la jsvc
-rwxr-xr-x 1 root root 95479  4月 19 18:29 jsvc
起動スクリプトの編集
$ sudo cp /usr/java/apache-tomcat/bin/jsvc-src/native/Tomcat5.sh /etc/init.d/apache-tomcat
$ sudo chmod a+x /etc/init.d/apache-tomcat
/etc/init.d/apache-tomcat
--snip--

LANG=C
#JAVA_HOME=/home2/java/j2sdk1.4.2_03
JAVA_HOME=/usr/java/jdk
#CATALINA_HOME=/home/tomcat5/tomcat5/jakarta-tomcat-5/build
CATALINA_HOME=/usr/java/apache-tomcat
#DAEMON_HOME=/home/jfclere/daemon
DAEMON_HOME=$CATALINA_HOME
#TOMCAT_USER=tomcat5
TOMCAT_USER=root

# for multi instances adapt those lines.
TMP_DIR=/var/tmp
PID_FILE=/var/run/jsvc.pid
#CATALINA_BASE=/home/tomcat5/tomcat5/jakarta-tomcat-5/build
CATALINA_BASE=$CATALINA_HOME

#CATALINA_OPTS="-Djava.library.path=/home/jfclere/jakarta-tomcat-connectors/jni/native/.li
bs"
CLASSPATH=\
$JAVA_HOME/lib/tools.jar:\
$CATALINA_HOME/bin/commons-daemon.jar:\
$CATALINA_HOME/bin/bootstrap.jar

case "$1" in
  start)
    #
    # Start Tomcat
    #
    #$DAEMON_HOME/src/native/unix/jsvc \
    $DAEMON_HOME/bin/jsvc-src/jsvc \
    -user $TOMCAT_USER \
    -home $JAVA_HOME \
    -Dcatalina.home=$CATALINA_HOME \
    -Dcatalina.base=$CATALINA_BASE \
    -Djava.io.tmpdir=$TMP_DIR \
    -wait 10 \
    -pidfile $PID_FILE \
    -outfile $CATALINA_HOME/logs/catalina.out \
    -errfile '&1' \
    $CATALINA_OPTS \
    -cp $CLASSPATH \
    org.apache.catalina.startup.Bootstrap
    #
    # To get a verbose JVM
    #-verbose \
    # To get a debug of jsvc.
    #-debug \
    exit $?
    ;;

  stop)
    #
    # Stop Tomcat
    #
    #$DAEMON_HOME/src/native/unix/jsvc \
    $DAEMON_HOME/bin/jsvc-src/jsvc \
    -stop \
    -pidfile $PID_FILE \
    org.apache.catalina.startup.Bootstrap
    exit $?
    ;;

  *)
    echo "Usage tomcat.sh start/stop"
    exit 1;;
esac
* 最初のLANG=Cを指定しないと後でLucene Web Serviecが返す日付がおかしなことになる

Lucene Web Serviceのインストール

ここからwarファイルをゲット webappディレクトリにコピー
$ sudo cp lucene-ws-1.0_01.war /usr/java/apache-tomcat/webapps/
tomcatを起動すると自動的に展開されるのでシンボリックリンクを張っておく
$ sudo /etc/init.d/apache-tomcat start
$ sudo ln -s /usr/java/apache-tomcat/webapps/lucene-ws-1.0_01 /usr/java/apache-tomcat/webapps/lucene
WEB-INF/web.xmlをチェック WEB-INF/web.xml
<?xml version="1.0"?>
<web-app>

    <display-name>The Lucene Web Service</display-name>

    <servlet>
        <servlet-name>LuceneWebService</servlet-name>
        <servlet-class>net.lucenews.LuceneWebService</servlet-class>

        <!-- ADJUST THESE SETTINGS BELOW AS NECESSARY -->
        <!--
            In the presence of 'properties.file' it detected, web service will attempt
            to repopulate parameters with those found within the file pointed to by
            the 'properties-file' name/value pair value.
        -->
        <init-param>
            <param-name>properties-file</param-name>
            <param-value>/var/local/lucene/service.properties</param-value>
        </init-param>
        <init-param>
            <param-name>debug</param-name>
            <param-value>1</param-value>
        </init-param>
        <init-param>
            <param-name>directory</param-name>
            <param-value>/var/local/lucene/</param-value>
        </init-param>
        <init-param>
            <param-name>operator.default</param-name>
            <param-value>AND</param-value>
        </init-param>
        <init-param>
            <param-name>field.default</param-name>
            <param-value>all</param-value>
        </init-param>
        <init-param>
            <param-name>title</param-name>
            <param-value>Lucene Web Service</param-value>
        </init-param>
    </servlet>

    <servlet-mapping>
      <servlet-name>LuceneWebService</servlet-name>
      <url-pattern>/*</url-pattern>
    </servlet-mapping>

</web-app>
/var/local/lucene/が必要そうなので掘っておく
$ sudo mkdir /var/local/lucene
tomcatの再起動
$ sudo /etc/init.d/apache-tomcat stop
$ sudo /etc/init.d/apache-tomcat start
ブラウザからhttp://localhost:8080/luceneにアクセスすると
<?xml version="1.0" encoding="UTF-8" standalone="no"?><service xmlns="http://purl.org/atom/app#">
	<workspace title="Lucene Web Service (v0.75)">
		<collection href="http://localhost:8080/lucene/document/" title="document">
			<member-type>entry</member-type>
		</collection>
	</workspace>
</service>
とか返ってくるので動いていそう。

Javaはずいぶん長いこと触ってないないので間違っていたらツッコミよろしくです。

CentOS 5を入れていて気がついたのですが、CentOS 5のkernel-2.6.18-8.1.1.el5では(多分インストール時の2.6.18-8.el5でも)あらかじめタイマー割り込みのCONFIG_HZの値が100になっているので、カーネルの更新のたびに再コンパイルが必要なくなっていました。

include/asm-i386/param.h
- snip -
#ifndef HZ
#define HZ 100
#endif
- snip -
ただカーネルオプションの指定は必要みたいです。
- snip -
title CentOS (2.6.18-8.1.1.el5)
        root (hd0,0)
        kernel /vmlinuz-2.6.18-8.1.1.el5 ro root=/dev/VolGroup00/LogVol00 clock=pit nosmp noapic nolapic
        initrd /initrd-2.6.18-8.1.1.el5.img
- snip -

今のところntpの補正範囲から大きくずれることはないです。

詳しくはこの辺。
Clock in a Linux Guest Runs More Slowly or Quickly Than Real Time (VMware)

天気があまりに良かったので土曜日に葛西臨海公園に行ってきました。
んで、携帯だけどなかなかかっちょいい写真が撮れたのでアップ。

途中曇ってきたけどこの季節は最高。

2007041401.jpg

2007041402.jpg

水族館にも行ってきました。

2007041403.jpg

2007041404.jpg

2007041405.jpg

調子乗ってパシャパシャ撮ってたら携帯の電池なくなりました。
そろそろ替え時かの。

Fedoraのlegacy supportに不安を覚えていたのでCentOS 5のリリースを受けて移行します。

2007041701.jpg

当たり前だけどパッケージはほとんどFedoraと変わらんです。
余裕があったらGFSなんか試してみたいなと。

item233860p1.jpg
Make Your Own Kind Of Music / Mathieu Bouthier & Muttonheads
  • Label: Serial
  • Release: 2007/03/26
  • A1. Make Your Own Kind Of Music [Original Mix]
  • B1. Make Your Own Kind Of Music [The Frenchmakers Remix]

ようやくLOSTのシーズン2を見終わりました。ただ毎晩寝る前に見たのでところどころ記憶がないです。もう一回通して見なきゃです。

LOSTって音楽を結構意識してる感があります。エピソードの終わりに長めにかかけて印象付けたり、随所に音楽が出てきます。そんな中、気になっていた曲がシーズン2の第二話でデズモンドがハッチの中でかけていた曲。同じようなフレーズがリフレインされるような曲で印象に残ってて、誰の曲か調べたらMama Cass Eliot (Mamas & Papasの Cass Eliot)のMake Your Own Kind Of Musicだそうです。

で、ものすごいナイスタイミングでリリースされたのがこれ。Make Your Own Kind Of MusicのHouse remix。フランスのSerial Recordsってレーベルなんですが、よく知らなかったのでサイトに行って見ると結構フィルター系のナイスチューンが揃ってます。

で、曲の方はA1のOriginal Mixは原曲のサビのフレーズを使ってのHappy tune。I Love NYのSeasons of Loveみたいにディスコなフィルタートラックに古い音源のボーカルが気持ちいいです。B2はガラッと変わってサビをこれっぽちも使わないリミックス。トラックはこっちの方がいいのでちょっと惜しい感じ。

最近またフィルター系にはまりがちかも。

ちなみに原曲はこのアルバムに入ってるそうな。

Dream a Little Dream of Me: The Music of Mama Cass Elliot
Mama Cass Elliot
Universal International (2005/05/10)
売り上げランキング: 7616

要はDBIC::Schema::Loader(0.03010)でSQLiteを使う場合、CREATE TABLEを全部小文字で書くとUNIQUE制約が見つからずにfind_or_createの時に困る件。

こんなテーブルがあった場合、

db/myapp.sql
create table users (
	id integer not null primary key,
	username text not null unique,
	email text not null unique,
	password text not null
);

要はusename, emailにはUNIQUE制約が付いていてpasswordには付いていない場合。

DBIC::Schema::Loaderを使えば自動的にスキーマを作ってくれる。

lib/MyApp/Schema.pm
package MyApp::Schema;

use strict;
use base qw/DBIx::Class::Schema::Loader/;

__PACKAGE__->loader_options(
    relationships => 1,
    debug         => 1,
);

1;

ここでUNIQUE制約を自動的にadd_unique_constraint()してくれると期待しても

MyApp::SchemaUsers->load_components("PK::Auto", "Core");
MyApp::SchemaUsers->table("users");
MyApp::SchemaUsers->add_columns(
  "id",
  { data_type => "integer", is_nullable => 0, size => undef },
  "username",
  { data_type => "text", is_nullable => 0, size => undef },
  "email",
  { data_type => "text", is_nullable => 0, size => undef },
  "password",
  { data_type => "text", is_nullable => 0, size => undef },
);
MyApp::SchemaUsers->set_primary_key("id");

add_unique_constraintしてる気配なし。

これはDBIx::Class::Schema::Loader::DBI::SQLiteの_sqlite_parse_tableでUNIQUE制約を探す正規表現にiオプションがついていないのが原因。

create table users (
	id integer not null primary key,
	username text not null UNIQUE,
	email text not null UNIQUE,
	password text not null
);

なら動くという・・・

MyApp::SchemaUsers->load_components("PK::Auto", "Core");
MyApp::SchemaUsers->table("users");
MyApp::SchemaUsers->add_columns(
  "id",
  { data_type => "integer", is_nullable => 0, size => undef },
  "username",
  { data_type => "text", is_nullable => 0, size => undef },
  "email",
  { data_type => "text", is_nullable => 0, size => undef },
  "password",
  { data_type => "text", is_nullable => 0, size => undef },
);
MyApp::SchemaUsers->set_primary_key("id");
MyApp::SchemaUsers->add_unique_constraint("username_unique", ["username"]);
MyApp::SchemaUsers->add_unique_constraint("email_unique", ["email"]);

FOREIGN制約とかはちゃんとiオプションつけてるので何か理由があるんでしょうかね?

追記:
http://lists.scsys.co.uk/pipermail/dbix-class/2007-April/003653.html
というわけでただのバグでそのうち直すそうです。

追記:
http://search.cpan.org/src/BLBLACK/DBIx-Class-Schema-Loader-0.03011/Changes
0.03011でパッチがあたってfixされた模様。

金曜日に東京ドームで巨人-阪神ナイター観戦。

2007040601.jpg

全く打線がつながる気配を見せず6-1で完敗・・・

土曜日に埼玉スタジアムで浦和-磐田ナイトゲーム観戦。

2007040702.jpg

ひたすら守りに入って2-1で辛勝・・・

日曜日に再び東京ドームで巨人-阪神ナイター観戦。

2007040801.jpg

浜中・関本を戻して打線沈黙で2-0で完封負け・・・

不貞寝。

2007040701.jpg

去年に続きperl mogerの祭典YAPC::Asia 2007に行ってきました。

どれもこれも濃い内容だったので、自分のメモ用に気になったのだけ。

Perlネットワークプログラミング再考 / Naoya Ito

ネットワークプログラミングはJavaで書いたっきりだったのでちょっと懐かしい気分で聞いてました。 Javaに比べるとかなりローレベルで濃い内容だったけど面白かったです。 説明になかったAsynchronous I/OってのはJavaでいうとこのNIOになるのかな?

Everything Vox / Ben Trott

Everythingというだけあってサーバー環境からCatalystからかなり広範囲でした。 キャッシングやパーティショニング辺りは事例でよく出てくるmixiやlivedoorとかと同じような仕組みだったので、前々からパーティショニングした場合の横断検索(全ユーザーを対象とした全文検索など)なんかはどうすんだろ?って疑問をぶつけてみたのですが時間が少なかったのとボクの説明不足で今一理解には達しませんでした。Catalyst::ModelとData::ObjectDriverの関係がどうなってんのかとかと合わせて、この次の機会に聞いてみたいと思います。

Perl 6 Today / Audrey Tang

相変わらずの難解なプレゼン。もはやPerlのプレゼンの域を超えてました。 でも、前回のを聞いていたのと自分で触っていたので前回よりは理解できた・・・つもりです。 前回も思ったけど、サンプルコードが難しくて集中力を要するプレゼンでした。

Introduction to DBIx::Class / Jonathan Rockway

"Introduction"だけにかなり基本的な内容でしたが、気になったのがスキーマのdeployをかなり使ってるってとこでした。使ってない(ってかまともに動いたことない)のですが、将来的にバージョニングなんかもサポートされるみたいないのでちょっと真面目に触ってみようと思います。 あと、このセッションではないのですが" Building Catalyst Applications"の方でDBIC::Schema::Loaderでdynamicではなく、staticに書いてdeployするほうがいい、みたいなことを言ってたのが、Atsushi Kobayashiさんのセッションで進めていたDBIC::Schema::Loaderをバリバリ使おうという意見と違ってて興味深かったです。 ボクは後者なんですが、前者も試してみようと思いました。

Behind the Scenes at LiveJournal: Scaling Storytime / Brad Fitzpatrick

基本的に前日のVoxの話と大分かぶっていましたが、こちらの方がさらに環境周りに突っ込んだ内容でした。 GearmanとTheSchwartzの違いがクライアント/サーバーなのかライブラリなのかの違いしか理解できませんでした。danga.comを真剣に漁ってみようと思います。

関係者の方々お疲れ様でした。
来年も是非よろしくです。

セリーグが先週末から開幕して今年も楽しみな季節になりました。
というわけで、今年の阪神の関東遠征初戦、ヤクルト-阪神を見に小雨の神宮球場に行ってきました。

2007040302.jpg

先発は今年から入ったジャン。
無茶苦茶でかい体から豪快なフォームで投げるし、バッティングもホームラン打つ気バリバリで好感持てました。

2007040303.jpg

兄貴のバースデー満塁ホームランで楽勝・・・と思いきやジャンが捕まってあっという間に1点差でしたが

DK

2007040304.jpg

J

2007040305.jpg

F

2007040306.jpg

と今年から順番が変わったJFKで逃げ切りました。

2007040308.jpg

今日は何と言ってもこの人。
39歳の誕生日を自分で祝っちゃう4回の満塁ホームランと8回の好返球で独り舞台。
もう大好きっす。
ピンクのネックレスも許します。

2007040307.jpg

これで三連勝で今シーズン初の首位。
今年一発目の六甲おろしが気持ちよかったです。

甘いもの大好きです。
糖尿病まっしぐらです。

そんなボクが、前々から気になっていたのが去年の暮れに新宿南口のサザンテラスにオープンしたクリスピー・クリーム・ドーナッツ
実はあの辺はほとんど行かないので(いつも高島屋のHMVでUターン)、そんなものができたことさえ知らなかったです。
3月くらいにたまたま通ったときに橋の辺りから匂ってくる甘い香りと、ありえない行列に興味を引かれてたどってみて初めて知りました。
以来、通るたびに食べたいと思っていたのですが、毎回ディズニーランドなみの行列に諦めていました。
が、昨日、お友達が朝11時に買いに行ってくれてゲットしてくれました。
11時の時点でばら売りだと1時間待ちパックだと20分待ちだったそうです。
オツ!>A嬢

2007040301.jpg

で、感想。
テイクアウトの箱には「8秒くらい電子レンジであたためるとおいしく召し上がれます。」と書いてあったので言われるがままチン。
ミスタードーナッツとかに比べるとかなり生地は柔らかめでした。
チョコレートは濃い目で甘さも思ったよりは控え目。

あっという間に6個なくなりました。
今日の夕飯は残り6個です。

以前、DBIx::Class::DigestColumnsの問題というエントリーでDBIC::DigestColumnsがいまいち使いづらいようなことを書きましたが、今年に入ってアップデートされてちょっと便利になった模様。
ユーザー管理で生パスワードを保存したくない場合には結構便利なコンポーネントです。

テーブルを作って
create table users (
    id integer not null primary key,
    username text not null,
    password text not null
);
schemaクラスはLoaderにまかせて
package MyApp;

use strict;

use base qw/DBIx::Class::Schema::Loader/;

__PACKAGE__->loader_options(
    components    => [qw/DigestColumns/],
    relationships => 1,
);

1;
resultクラスでDigestColumns周りの設定を追加
package MyApp::Users;

use strict;

__PACKAGE__->add_column(
    'password' => {
        digest_check_method => 'check_password',
    }
);

__PACKAGE__->digestcolumns(
    columns   => [qw/password/],
    algorithm => 'SHA1',
    encoding  => 'hex',
    auto => 1,
    dirty => 1,
);

1;
こんな感じのスクリプトを走らせると
use strict;
use warnigs;

use MyApp;

my $schema = MyApp->connect('dbi:SQLite:db/myapp.db');

# Userを追加
my $user = $schema->resultset('Users')->create({
    username => 'foo',
    password => 'bar',
});
# passwordには 'bar' のハッシュ値が入ってる
print "username: ", $user->username, "\n";
print "password hash: ", $user->password, "\n\n";

# usernameを変更
$user->update({
    username => 'baz',
});
# dirty => 1 してあると明示的に指定しない限りハッシュカラムは変更されない
print "username: ", $user->username, "\n";
print "password hash: ", $user->password, "\n\n";

# passwordを変更
$user->update({
        password => 'baz',
});
# 明示的に指定するとpasswordには新しい値のハッシュ値が入る
print "username: ", $user->username, "\n";
print "password hash: ", $user->password, "\n\n";

# columnオプションにdigest_check_method => 'check_password'を指定してあると
# 自動的にcheck_passwordメソッドが追加されて評価ができる
print "check password w/ bar: ", $user->check_password('bar'), "\n";
print "check password w/ baz: ", $user->check_password('baz'), "\n";
こんな結果
username: foo
password hash: 62cdb7020ff920e5aa642c3d4066950dd1f01f4d

username: baz
password hash: 62cdb7020ff920e5aa642c3d4066950dd1f01f4d

username: baz
password hash: bbe960a25ea311d21d40669e93df2003ba9b90a2

check password w/ bar:
check password w/ baz: 1
ポイントは
  • dirty => 1オプションを付けるとdigestカラムは明示的に指定しない限り変更されなくなった。
  • add_columnでカラムにdigest_check_method => $method_nameを追加すると$method_nameでハッシュ値の評価ができるようになった。

日曜日に新宿御苑に行ってきました。
いい天気だったこともあり、あり得ない人の数でした。

2007040103.jpg

2007040104.jpg

2007040105.jpg

思ったより葉っぱが出てきてしまっていましたが、午後からちょうど花吹雪が舞うようになって綺麗でした。

2007040107.jpg

2007040108.jpg

2007040109.jpg

日曜日に新宿御苑に行く途中に花園神社に久々に立ち寄りました。
意外と趣があっていい感じです。

2007040101.jpg

2007040102.jpg

土曜日に国立に行ってきました。
学園通りが見事な桜のトンネルになってました。

2007033101.jpg

2007033102.jpg

夜の大学通りの桜。
大学通りは駅がなくなっちゃったので歩道橋からの絶好ポイントが魅力減でした。

2007033103.jpg

2007033104.jpg

プロフィール

このアーカイブについて

このページには、2007年4月に書かれたブログ記事が新しい順に公開されています。

前のアーカイブは2007年3月です。

次のアーカイブは2007年5月です。

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