rubykaigi.orgの歴史

whoisしてみると分かるようにrubykaigi.orgドメインは現在私が所有している。

元々RubyKaigiは独自のドメインというのは持っていなかった。その頃、確か高橋さんか角谷さんにだったと思う、rubyconfみたいにドメイン取らないのかと聞いてみた。取るつもりはないというお答えであった。思うに、当時は今にも増してイベントの継続性は神のみぞ知るところだったわけで、ドメインを取ってそこで継続的にサイトをメンテナンスするのはそぐわないということだったのだろう。

それにしても、RubyKaigi 2007が行われようかという時点で既にruby-talkruby-coreでも"RubyKaigi"という文字を目にするようになっていた。と、すればいずれここに目を付けるスパマーもいるだろう。みすみすこのブランドをスパマーにスクワットされるがままに放置しておくのは惜しいように思われた。そこで私が勝手にrubykaigi.orgを登録してRubyKaigi 2007のサイトに転送するように設定して運用していたのである。

その後、実行委員会は方針を変えたようで角谷さんから「rubykaigi.org持ってるよね?」と連絡があった。必要ならいつでも引き渡すよーとは言ったのだけれどもなんか特に必要にも迫られなかったので、結局所有者兼ドメイン設定担当者みたいな形でずるずるとここまでやってきている。角谷さんから要請があるとその都度私がDNSレコードを変更したりしていた。

この度、日本Rubyの会が法人格を取得すると言うことで、関係する個人ではなく会そのものがドメインを所有することもできるようになる。そこで「近いうちにrubykaigi.orgは日本Rubyの会に引き渡そう」という話をしたりもした。それで、思い出話を書いてみた。

Googleによるトランスセクシュアルへの配慮の事例

先に報告した ようにこのたびGoogleに転職した。

ここで、Googleトランスセクシュアルへの対応に感心したので書いておく。

履歴書

まず、US系の企業としては当たり前の慣習であり法的自己防衛でもあるのかもしれないけど、履歴書に性別を書かされない。

背景

履歴書に書くべき何か簡潔な性別の記述というものが存在するのであれば私にとっては問題ないのだけれども、実際のところはそうではない。

この話は 以前も書いた

人は性別という単一の二値属性が存在することを信じるが、残念なことに自然はそういう風にはできていない。人の信じる仮構は単に、少数者を例外として排除してしまえば幾つかの性別要素にまつわる量が成す数ベクトル空間について2つの同値類が存在し、それを「男」「女」と呼べるというだけの話に過ぎない。

残念なことに最初に省いた特異点を含めると単純な同値類は成立しない。都合の悪い例から逃げずに一般にこの空間の性質について話をするならば、性別というものは「今どの切り口におけるどういう定義での性別を必要としているのか」「仮に性別属性を二値に落とすとして、二値の境界をどこに置くか」を与えなければ記述が困難だ。

上掲記事のように数ベクトルを成す個々の値についての話を羅列して、これが私の性別であると述べることは可能かも知れない。しかしおよそ、一般に簡潔な表記が得られるとは限らない。そして見ての通り、私が試みた自己の記述は簡潔ではない。あれでも、あんまりみんなを煩わしてはいけないと思って多少の不正確は覚悟の上で若干の情報をそぎ落としてあるんだけどね。 *1

大抵の書類は受付者が必要としている性別の定義を書いていない。だから私は上のようなことを毎度毎度考えたあげくに、この人はどの定義における性別情報を必要としているのだろうか、私にとってはこれは面倒で下手をすれば性別違和感を喚起される甚だ不快なことなんだけれども、そもそも私の辛抱に見合うほどこの人はこの情報を必要としているのだろうか、また、この場面においてこの切り口の性別情報を提示させることは政治的に適切な態度だろうか *2 と悩むことになる。

Googleの場合

Googleの採用ページ には、「性別、生年月日、年齢、門地、兵籍、国籍、個人識別番号等を書くな」とある。

これらは確かに採用に当たって能力を測るには必要がない。またこれらの情報を知らなければ、性差別をするつもりなのではないか、年齢差別をするつもりなのではないかと勘ぐられずに済む。合理的である。

以下で見るように入社前後の手続きで性別にまつわる何らかの属性情報を必要とする局面は確かにあるのだけれども、そんなものは血圧やコレステロール値と同じく、採用を決めて必要になってから必要な限度において収集すればよい情報である。

労務系

社会保険に健康保険、雇用における男女共同参画の資料やらなんやら、労務系の資料では「法律上の性別」が必要となる局面が存在する。

Googleでも入社するとこれらの手続きのために必要な情報を提供するように求められる。今回私はこの段階になって担当者に次のようなメールを送った。

レジュメから参照可能なオンラインリソースにも明記してありますのでご存知かも知れませんが、私はトランスセクシュアル(MtF-TS)です。このため、現在の戸籍/法律上の性別と社会生活上の性別は異なります。入社手続きフォームは主としてlegalな手続きのためのものとお見受けしましたので性別欄は戸籍上のデータ(男性)を入力しましたが、もし社会生活上のデータが必要でしたらご相談ください。

フォームの趣旨に関する私の推量は適当だったようで、その旨返信があった。当たり前だけれどもGoogleはこの点ではフェアな会社である。上のような申告で特に問題は無かった。

性同一性障害に関する判例の中では、大きな問題となって「選考過程で虚偽の申告があったため解雇」とかいうことで係争になった事例もある。その点でGoogleはまともな会社である。

医療系など

これだけであれば私は特にこの記事を書こうと思うことはなかったろう。その後、人事の方からフォローがあった。曰く、

  • USではトランスセクシュアルの従業員もそれなりにいるが、東京ではまだ事例が少ないので今後のために何か改善してほしい点などがあれば教えて欲しい。
  • 今後、特に健康診断などで不愉快な思いをさせないかと心配しているが、どのような対応を希望するか

    • 基本的には契約した病院の集団検診に参加して貰っているが、これは不愉快な思いをさせるのではないか
    • 契約した病院に個別の健康診断を依頼したほうがよいか
    • その他の方法があるか

これについて、私は次のように答えた。

  • 入社手続きフォームの性別(Sex)という記入欄は、どのような性別を意図しているのか推察可能ではあるけれども明瞭ではないので法的性別(Sex in Law)などのように明確にしてほしい
  • 健康診断については配慮して頂いて有り難い

    • 集団検診についても、事前に病院に話を通して頂いてちょっとだけ配慮を頂けるならば(個人的には、検診のやり方の詳細をその場で訊いた限りでは)問題ないように思える
    • 個別に依頼してもらえるのが最も良いように思える。その場合も会社から病院に話を通しておいて頂けると有り難い。
    • 埼玉社会保険病院のように、性同一性障害者の健康診断の事例の豊富な病院もあるので、健康診断で必要な検査項目をリストして貰えればこちらで検診を受けてくることも可能である。(私は塚田攻医師に相談して、以前の健康診断はこちらで受けた)
  • 私は性同一性障害者であることをオープンにしているが、すべての当事者がそうであるとは限らない。ヘイトクライムの危険性などもあるので性同一性障害であることの情報は本人の判断に沿って管理されるべきである。今後オープンにしないことを希望する当事者が入社したらそのように対応して欲しい。

  • ここでの私の回答はあくまでも私の場合の個人的な回答であって一般化はできないので、個々の事例ごとに対応して欲しい

日本の医療は健康保険を通じて法的性別と医療上の性別とが接する場であるので、両者が一致しないケースや医療上の性別を単純に男性もしくは女性と記述できないケースでは問題になりやすい。一方、トランスセクシュアルであっても完全にSRSを終え、法的性別の変更を済ませてしまっている場合はあまり問題にならないと考えられる。

その他

また

  • 社内のLGBTIのためのコミュニティとしてGayglersというのがあるので見てみてはどうかと案内してもらった
  • ここでは伝え忘れたけれども、労務系のための法的性別の収集と社内のプロフィール設定における社会的文化的性別(Gender)の入力が独立しているのは素晴らしいと思った。
  • 開発合宿や研修旅行の目的でで温泉などを利用する場合、浴室設備が大浴場だけだと、SRSを受けていないトランスセクシュアルの利用に際して摩擦が発生しやすい。以前に提唱された解としては近場にビジネスホテルの部屋を別途用意するなどの対応が考えられる。これにしても問題が無いわけではないけれど、間に合わせの回避策としてはとりあえず機能するだろう。

考察と展望

このように、プロフェッショナルな仕事をする人事がいれば従業員がトランスセクシュアルであることは問題にならない。

トランスセクシュアルと労働というと、日本では何かと暗い話題もよく耳にする。やれ、面接で侮辱的な扱いを受けただの、性同一性障害であることを理由に解雇されただのと。しかしWeb業界は、全体に若い業界であることも手伝って既に「トランスセクシュアルかシスセクシュアルかなど、仕事に当たって気にする方がおかしい」という流れである。少数の変な信念を持った差別的な企業があってもじきに淘汰されよう。

これから職に就こうとする若いトランスセクシュアルに特に伝えたい。あなたは何にでもなれる。もう時代は変わった。だから、トランスセクシュアルであることで何か職業選択上の可能性が制約されるとは考えないで欲しい。

Web業界でLGBTであるということを理由に積極的に排除しようとする人はほとんどいない。日系の大きな組織になると、銀行系の妙な人材が経営層に流れ込んでいる関係か少しばかり硬直的な制度があることもある。けれども、それは交渉すれば変えられるものだ。なんと言っても現場の人たちは味方なのだから。 *3

それに企業は日系企業だけではない。たとえばGoogleもまた、LGBTに対してフェアである。採用時の差別は存在しないと思われる。よく分からないことについては相談しつつ、喜んで多様性に対応できる人事がいる。法的性別、医療における性別、社会生活における性別が必ず一致すると仮定した誤った設計の社内システムが存在しない。

世界はあなたに対して開けている。私はこれを理解しているつもりで、そして 私自身が一つの事例を提供し続けることで後の世代に伝えたい と思ってきた。しかし、私は理解していなかった。私が肩肘張って自力ですべてを変える必要もないのである。

今回Googleの人事はプロの仕事をして、受動的に必要な対応をしてくれるだけでなく積極的に動いてくれた。世界には優秀な人たちがいて、世界はこんなにも開かれている。

*1:具体的な数値はそれこそプライベートなことだし、記事を書くときに検査票を資料の山から引っ張り出すのも面倒だったので

*2:センシティブかつプライベートな問題であるので、社会的に適切とされている以外の軸についての性的属性の収集は一般的に言って性差別またはセクシュアル・ハラスメントである。例えば職場でパンツの色を聞いたり包茎かどうかを問題にするなど。勿論、性的なジョークが許される間柄ならば良いけれども、一般的に職場で性器の形態について問題にするのは望ましいことではない。トランスセクシュアルがしばしば直面する、社会生活上の性別が必要とされるべき局面で医療的性別情報を要求される類も同様にしてセクシュアル・ハラスメントに包括されると私は考える。「セクシュアリティに関する射影関数の不適切な選択」がセクシュアル・ハラスメントなのである。

*3:今回私は途中でうんざりしてきて日系企業の相手をするのはやめたからあんまり大きな口は叩けないけど

転職のお知らせ

世間は地震により慌ただしい。震源地近くの被災者の方にはお見舞いを申し上げる。 この最中に、個人的な報告を投下するのはちょっと憚られるものもあるのだけれども、あまり時期を外しても書く機会を逸するので思い切って書くことにしよう。

1月一杯で約3年務めた 株式会社スケールアウト を辞め、3月1日から Google Japan で働き始めた。twitterでは大勢の方に祝っていただき有り難い限りである。

Googleについては特に語ることはない。みんなが知っているし、私もまだみんなが知っているようなことの他は僅かしか知らない。だからスケールアウトについて語ることにしよう。

株式会社スケールアウト

スケールアウトは広告配信エンジン/広告在庫管理システム/広告入稿システム/広告案件管理システムをフルスタックの製品「ScaleAds」を提供するスタートアップである。

創業

創業者の山崎大輔さんは、元はYahoo! Japanの広告配信システムを構築した人である。一部では「 最速配信研究会のid:yamaz 」と言ったほうが通りがよいかも知れない。 まだ日本のネット業界が成立するかしないかの頃、彼はまだそれほど大きくなかったYahoo!に入って、今の巨大なサイトで高速にアクセスごとに最も適切な広告を選択して配信しているシステムの構築に携わった。

山崎さんはその実績もあってYahoo! Japanではそれなりに地位を得ることができたが、ある日自分の伸び悩みを感じて「このまま会社にしがみついて生き残ることは可能かもしれないが、それでは老害と化してしまう」と判断し、社外に挑戦の場を求めて武者修行に出ることを決心したそうである。そうして、スケールアウトを創業した。

そのスケールアウト社が作ったのがScaleAdsである。Webコンテンツを持っている会社が自社サイトに載せる広告を管理することを主に想定しているが、それに限らない。実際、メールマガジンでの広告の管理にも対応しているし、汎用のコンテンツ配信管理システムとして設計されている。 月間10億インプレッション程度であれば鼻歌混じりに捌き、サボらずにまともに設定すれば僅かなサーバー数で100億インプレッションを処理する。理論的には1000億PVもOKだ。

参加

現在のWeb業界にとって広告はオフラインとWebを繋いで経済を循環させる太い血管である。この血管の構築に携わりたいと思って、私もScaleAdsの開発に途中から参加した。そして、在庫管理システム/広告入稿・案件管理システムの継続的な改善に取り組んだ。

山崎さんの知識に基づく強力な配信エンジンを持つScaleAdsであるが、一方フロントエンド側や中間処理は私が参加した時点ではスパゲティであった。このレガシーコードとの戦いが私の仕事であった。あれを見たときにはコードベースを捨てることを提案したが、さすがにそれは山崎さんによって却下された。

レガシーコードを動いたまま移行させるのは書き直すことに比べて遥かに高く付く。それでも、そのコストに組織やメンバーが耐えることができたなら、危険な大きなジャンプをすることなく、機能のデグレードにも見舞われることもなく持続的なメンテナンスの可能なコードベースに移行することができる。 振り返って考えるに、恐らくコードベースを捨てて作業すれば半年で移行できたであろうが、代わりに一時的に大きな障害を引き起こした可能性もあったろう。Webシステムにあって最も金銭に近い *1 部分の1つである広告システムでは、資金的余裕の少ないスタートアップにはそのような失敗は許されない。こうして我々は3年間にわたる茨の道を歩くことになった。

十分にモジュール化されていないシステムを切り開き、テストハーネスを取り付けた。移行用のテストを書いてはモジュールを移行させ、テストを捨てた。いや、捨てるべきテストを捨てきれずに失敗した部分もある。幾つかのテスト戦略を試しては、幾つかは失敗した。これによりシステムから少しずつ腐ったコードが無くなっていった。拡張可能性を手に入れたシステムに、幾つか大きな機能追加を施した。

この時期この部分の開発に携わったメンバーを聞けば、東京のWeb開発者コミュニティ(特にRubyScala)にいる人ならば、この製品がどういうものであるのか分かるだろう。

一応、会社のサイトで公開している(いた)メンバーだけリストしたけれども、他にも一時期手伝ってくれた人は大勢いる。

転職

スケールアウトの長い戦いは今収束しつつある。安定性を更に増すために継続的インテグレーションで処理するテストケースはもっと増やすべきだが、それにしても主なモジュールのスパゲティは解消した。コードベースは継続的なメンテナンスが可能なものになった。継続的インテグレーションやその他諸々開発インフラも整えた。事業的にも顧客を増やして成功してきている。

一仕事終えた私はここでスケールアウトを一時離れることにした。これには2つ理由がある。1つには苦闘の日々が一時収束したので、次の大きな機能拡張の時期が来るまでは他でもっと面白いことをしていたかった。ただ、退職を決めた後になってから「次の大きな機能拡張」が思ったより早く来そうなことが判明したので、これについてはちょっと早まった判断だったかも知れない。

もう1つは、先に述べたようにスケールアウトはYahoo! Japanからのスピンアウト組を含んでいるということが関係ある。彼らが持っている大きな組織での開発者の政治的力学の経験や異分野の尖った専門家との繋がりというものを見て、興味を持った。そしてそれを体験してみたくなったのだ。 このため今回の転職ではチームでそれなりに大きな規模で開発している会社というのを一つのコンセプトとした。

このコンセプトに沿い、かつ 私が望むweb に貢献する会社を探した。そしてたまたまGoogleとご縁があった。こうして転職したのである。

*1:「金銭そのもの」であるオンラインバンキングやトレーディングを除けば

Understanding Go compiler tools (2)

Today I read memory management in go compiler.

There are go.y , y.tab.[ch] , lex.c and other files in src/cmd/gc/ directory. It seems that the go compiler has a lexical analyzer written by hand and a syntax parser generated by yacc ( bison ). lex.c also contains the main function for the compiler.

Here are the head lines of main function:

int
main(int argc, char *argv[])
{
        int i, c;
        NodeList *l;
        char *p;

        signal(SIGBUS, fault);
        signal(SIGSEGV, fault);

        localpkg = mkpkg(strlit(""));
        localpkg->prefix = "\"\"";

        builtinpkg = mkpkg(strlit("go.builtin"));

        gostringpkg = mkpkg(strlit("go.string"));
        gostringpkg->name = "go.string";
        gostringpkg->prefix = "go.string";        // not go%2estring

        runtimepkg = mkpkg(strlit("runtime"));
        runtimepkg->name = "runtime";

....

It is easy to guess what they do. They initializes signal handlers and bootstrap some standard packages.

Also we can see the declaration of NodeList *l . The parser must be going to store the result into the list.

memory management

I guessed that strlit function converts a C string into a String representation for the compiler. It was correct. The definition of strlit is in subr.c and it returns a pointer to Strlit . Strlit in go.h is commented as:

/*
 * note this is the representation
 * of the compilers string literals,
 * it is not the runtime representation
 */

Here I wondered how the go compiler manages heap memory for Strlit and others.

In general, memory management is an important part, although not a core topic. This is because there are many object to allocate during parsing sources and compiling. A parser must try to parse any input. It allocates some memory whenever it reads a term, and little by little constructs a syntax tree.

I heard that gcc uses garbage collection to mange memory on parsing and compiling. Ruby interpreter (CRuby) uses Ruby's garbage collector in order to manage heap memory for parser.

In the case of Go compiler, memory management seems naive.

Strlit*
strlit(char *s)
{
        Strlit *t;

        t = mal(sizeof *t + strlen(s));
        strcpy(t->s, s);
        t->len = strlen(s);
        return t;
}

strlit just calls mal and copies data into the allocated memory. mal must be a wrapper of malloc .

Here is the source of mal :

void*
mal(int32 n)
{
        void *p;

        if(n >= NHUNK) {
                p = malloc(n);
                if(p == nil) {
                        flusherrors();
                        yyerror("out of memory");
                        errorexit();
                }
                memset(p, 0, n);
                return p;
        }

        while((uintptr)hunk & MAXALIGN) {
                hunk++;
                nhunk--;
        }
        if(nhunk < n)
                gethunk();

        p = hunk;
        nhunk -= n;
        hunk += n;
        memset(p, 0, n);
        return p;
}

For large n it just calls malloc . For small n it adjusts alignment and returns a part of memory pointed by hunk .

This is the implementation of gethunk . There is nothing special.

static void
gethunk(void)
{
        char *h;
        int32 nh;

        nh = NHUNK;
        if(thunk >= 10L*NHUNK)
                nh = 10L*NHUNK;
        h = (char*)malloc(nh);
        if(h == nil) {
                flusherrors();
                yyerror("out of memory");
                errorexit();
        }
        hunk = h;
        nhunk = nh;
        thunk += nh;
}

Here is the implementation of remal , you know, a realloc equivalent.

void*
remal(void *p, int32 on, int32 n)
{
        void *q;

        q = (uchar*)p + on;
        if(q != hunk || nhunk < n) {
                if(on+n >= NHUNK) {
                        q = mal(on+n);
                        memmove(q, p, on);
                        return q;
                }
                if(nhunk < on+n)
                        gethunk();
                memmove(hunk, p, on);
                p = hunk;
                hunk += on;
                nhunk -= on;
        }
        hunk += n;
        nhunk -= n;
        return p;
}

It cares the case of extending the last part of hunk , however, that's all. It leaves heap memory leaked. The heap memory is collected by the end of process.

The go compiler seems to manage heap memory really naively and generously.

Here is another example. struct Node , which is the representation of a node in syntax tree, is just a concatenation of members which are necessary for each type of node. It is even not an union.

struct Node
{

....

        // if-body
        NodeList*        nelse;

        // cases
        Node*        ncase;

        // func
        Node*        nname;
        Node*        shortname;
....
}

Conslusion

The go team does not seem to care about this kind part of the implementation. They prerfer keeping the source simple to strictly implementing it.

I think they have a plan to make the go compiler self-hosted. Go have a garbage collector, a parser generator and even a parser for Go. So they can replace the go compiler with one written in Go itself.

Understanding Go compiler tools (1)

Recently I read Go lang . I began to understand its structure.

How to build

You can build the go compiler and tools as documented in the official documentation .

It is quite easy. But it was confusing for me that I must run ./all.bash instead of usual make (1). I wonder why they don't simply use make . Anyway the bash script internally calls make as usual.

After building, I got the following executables in bin directory.

  • 6a: assembler
  • 6c: C compiler
  • 6g: Go compiler
  • 6l: linker
  • 6nm: same as nm(1)?
  • cgo
  • ebnflint
  • godefs
  • godoc
  • gofmt
  • goinstall
  • gomake
  • gopack
  • gopprof
  • gotest
  • gotry
  • govet
  • goyacc
  • hgpatch
  • quietgcc: gcc wrapper which is little slienter than native gcc

The oddish *1 prefix "6" is because I built the tools on amd64 architecture. The prefix varies according to architecture.

There are only three architectures which is implemented in the source:

This convention came from Plan 9 . I found the definitions for other architectures in include/mach.h :

2c(1) in Plan 9 describes one more architecture:

Directory structure

  • bin

    where executables will be generated into.

  • doc

    documentation

  • include

    C header files.

  • lib

    where some libraries will be generated into.

  • misc

    misc

  • pkg

    where Go standard packages (libraries) will be compiled into.

  • src

    source codes

  • test

    test cases

Let's dive into src :

  • cmd

    source codes for the Go tool chain

  • lib9

    Plan 9 C library?

  • libbio

    buffered IO library

  • libcgo

    ?

  • libmach

    library which contains architecture dependent codes

  • pkg

    source codes of Go standard packages

commands

Let's dive into cmd directory.

  • 5a/
  • 5c/
  • 5g/
  • 5l/
  • 6a/
  • 6c/
  • 6g/
  • 6l/
  • 8a/
  • 8c/
  • 8g/
  • 8l/
  • cc/
  • cgo/
  • cov/
  • ebnflint/
  • gc/
  • godefs/
  • godoc/
  • gofmt/
  • goinstall/
  • gomake/
  • gopack/
  • gotest/
  • govet/
  • goyacc/
  • hgpatch/
  • ld/
  • nm/
  • prof/

[568][acgl] directories contain architecture dependent part of the sources. Architecture independent parts of the Go compiler are in gc directory.

I will read the detail of gc in the next post.

*1:oddish, at least for me, who grew with GNU/Linux environment.

Localizing irb messages

Do you know rubyists in Japan use Irb in Japanese?

% irb --help
Usage:  irb.rb [options] [programfile] [arguments]
  -f            ~/.irbrc を読み込まない.
  -m            bcモード(分数, 行列の計算ができる)
  -d                $DEBUG をtrueにする(ruby -d と同じ)
  -r load-module    ruby -r と同じ.

Irb has had ability to localize the help message and some error messages, and has been shipped with Japanese localization by historical reason. Also I improved this localization mechanism so that messages are converted correctly with String#encode and that Irb can load a localization from a gem. But this fact is not well known. I could not find any other localization with Google search.

Recent events

Recently Abinoam Jr. wrote Portugese localization for IRB . He sent it to me and I suggested that he should distribute it as a gem.

At this time I found that the mechanism that load a localization from a gem is broken on Ruby 1.9.2. Anyway, I fixed the problem at r30448 and the next patchlevel release of Ruby 1.9.2 will be able to load a localization from a gem again.

How to write a localization for Irb

It is quite easy. Suppose that we are writing a localization for zh_JP.UTF-8@ancient locale and let /path/to/somewhere the working directory.

First, copy error.rb and help-message from $(rubylibdir)/irb/lc into /path/to/somewhere/irb/lc/zh_JP.UTF-8@ancient/ . *1

Second, translate the copies of error.rb and help-message into zh_JP.UTF-8 like this:

# -*- coding: UTF-8 -*-
律:  irb [選項] [簒譜] [参數]
-f          不讀~/.irbrc
-m          bc態(得簒分數行列)
....

Place the correct magic comments in both of the files.

Then, move the irb directory which contains the translated files into somewhere under $LOAD_PATH . I think $(sitelibdir)/ is preferred.

Finally you can distribute the irb/lc/<your-locale>/* as a gem instead of install it as a legacy style library. Ruby 1.9.1 and the next release of Ruby 1.9.2 can load a localization from a gem.

*1: Japanese localization has encoding_aliases.rb in addition to the two files. But encoding_aliases.rb is just for backward compatibility with Ruby 1.8. You don't have to implement it in your locale

コミケ79行

コミックマーケット79 に行ってきた。ずいぶん久しぶりの参加な気がする。昨日はPassengerの設定やらで明け方まで作業してしまったこともあるし、 昼頃からゆるゆると参加した。

ActiveWorksが復活して新刊出していたけどSymphony (PHP)ネタだったのでパス。代わりにSolaris本の前に逃したやつが今回は在庫があったので買ってきた。

途中、マイコン島に行くと、 イカ娘 の帽子を作ってるサークルがあって、新刊を買うついでに帽子も買った。実は、この手のイカ娘のなげやりコスはしたいなと思っていたのだけれども、制作が間に合わずに断念したので丁度良い。この帽子を被って他のサークルを回ったりした。

戦利品