Rails 2.2.2のI18n機能による日本語化がイケてない6つの理由
March 12th, 2009
Rails 2.2から導入されたI18nモジュールだが、さすがにバージョン0.0.1だけあって、実際に日本語でアプリを作ってみると細かいところでちょっとずつイケてなかったりするところが目につく。
以下に、僕が今までに気になったところを挙げてみよう。
1. ARのerror_messages_forでカラム名とメッセージの間に半角スペースが入る
active_record-2.2.2/lib/active_record/validations.rb 208行目より抜粋
1
| full_messages << attr_name + ' ' + message |
半角スペースハードコード!! このおかげで、例えば、「名前」カラムの必須チェックのメッセージが
「名前 を入力してください。」
というように表示されてしまう。半角スペースがめちゃめちゃ気になりますよね。
そこで、こんなチケットをあげて超いいかげんなパッチを投げてみたところ、どうやらそのままコミットされてしまったようだ。
これは、上記でハードコードされた半角スペースをリソースに出しちゃって各ロケールで再定義できるようにしちゃおう、という強引な解決法で、たとえば日本語だったら
1 2 3 4 | activerecord:
errors:
format:
separator: ""
|
な感じで空文字を設定してやると、無事に
「名前を入力してください。」
が出力できるようになる。
どんな言語でも ’ ’ か ” 以外の文字がここに設定されることは無いような気がするので、かなりムダな拡張ではあるのだが、他の部分のキー名との整合性を考えるとこんな感じにならざるを得ないところか。
どなたか他にもっと自然な実装があったら教えてください。Rails 2.3はまだRCだから今なら変更可能かもしれません。
2. Array#to_sentenceで半角スペースが入る
ActiveSupportには、Array#to_sentence という、少なくとも日本語のアプリでは誰も使ってないと思われるマイナー(かつ、Matzいわく、「ブレーキが壊れてる」)な機能がある。
で、Rails I18nプロジェクトでは当然これもローカライズの対象だったわけだが、Rails 2.2.2の実装では、どんなロケールでも
’, ’
でつなぐのは決め打ちで、最後の要素をつなぐフレーズだけandだったりetだったりundだったりできる、というだけ。で、「最後の要素の前に『カンマ』を入れるかどうか」をskip_last_comma ていう値で指定できるようになっていた。
これについては、もうちょっと汎用的にしようよ、ということで、’, ’ の部分も含めてロケールごとに設定できるように変更したパッチを送りつけてみた。
これで、Rails 2.3だと無事にこういうふうになった。
1 2 | >> %w[部屋 Yシャツ 私].to_sentence => "部屋とYシャツと私" |
あんま嬉しくない?
3. 容量の単位のやつで半角スペースが入る
これもマイナーな機能なのでどうせ誰も使ってないだろうし、なんか説明がめんどくさくなってきたから簡単に書くと、以下のような機能があるのだが、
1 2 | >> helper.number_to_human_size 1024 * 1024 * 100 => "100 MB" |
これもRails 2.2.2では数値と単位の間の半角スペースがハードコードされていたのが、こちらの掲示板で「どうよ?」って訊かれたので、「日本人的にはスペース空かないほうが嬉しい」って要望を伝えたら、そのとおりに実装してくれた。
なので、Rails 2.3からは
1 2 | >> helper.number_to_human_size 10000 => "9.8キロバイト" |
とかそんなふうに出力できるようになってます。GJ, Yaroslav!
4. Ruby 1.9に対応してない
Rails 2.2のI18nモジュールはRubyの最新安定版である1.9系では動作しない。
が、このへんのコミットで、Rails 2.3.1ぐらいからやっと Ruby 1.9に対応できたはず。こんにちは、ゆきひろさん!
5. datetime_selectが致命的にダサい
I18n.locale = :ja 状態で Svenのリポジトリ内の日本語リソースファイルを使って date_selectやdatetime_selectを表示してみると、以下のような感じで、致命的にダサくて悲しいコントロールが描画される。

これを解消するにはまぁとりあえず
1
| ja.date.abbr_month_names を [~, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12] |
とかにしてやると「月」は出なくなるのだが、これでも数字っぽいドロップダウンが3つとか並んでるだけで、なんのコントロールなんだかよくわからない。やっぱり日本人向けにはドロップダウンの間に「年」とか「月」とかっていう字が入ってるコントロールが欲しいわけだが、これはさすがに日本ローカル過ぎてActionPackに入れてもらうには無理がある。
つまり、今のRailsの標準部品ではどうやっても僕らが望む形のdate_selectは作れないので、日付のヘルパーにはelm200さんのdatetime_helper_jaを使うがよいです。datetime_helper_jaはRails 2.3でもばっちり動作します。
6. YAMLファイルを手で書くのがつらすぎる
i18n_generatorsを使えばいいと思うよ。i18n_generatorsはRails 2.3にも完全対応しています。
./script/generate i18n ja
結論
というわけで結論。
Rails 2.2系で日本語なアプリを作ってる人は、上記のようにI18nがいろいろアレでイマイチなので、とっとと2.3に移行しちゃうがよいと思います。



Ruby-GetText-Packageをメンテナンスしているむとうと申します。
>どなたか他にもっと自然な実装があったら教えてください。
そもそも「主語が文章の左に来る」「主語とそれ以外は何かで区切るかもしれない」という2つの前提は、全ての言語を網羅するには不十分だと思います。たとえば、右から左に表記する言語では主語は右に来るかもしれませんし、言語によっては文章の真ん中に来るかもしれません。
Gettextファミリーでは、このようなセンテンスは、そのセンテンスを丸ごと翻訳ファイルに抜き出す、ということで問題を回避します。 たとえば、 ”%{name} is invalid.” とします。%{name}の部分は変数です。 上記のようになっていれば、日本語ではたとえば、 ”%{name}は不正です。” とそのまま主語と述語の間をつなぐことができますし、 右から左に進む言語では “dilavni si %{name}” のようにかけるかもしれません。 Rails I18nでも同様の仕掛けがあって実装は容易だと思うのですが、なぜ、そのままにしているか不明です。
単語区切りのスペースの有無は文脈依存という言語がありませんでしたっけ。
> むとうさん
コメントありがとうございます!Gettextにはいつも大変お世話になっております。
>そもそも「主語が文章の左に来る」「主語とそれ以外は何かで区切るかもしれない」という2つの前提は、全ての言語を網羅するには不十分だと思います。
そうなんですよね。まさにおっしゃるとおりだと思います。
自分も最初パッチを書いたときは、どうせならGettextのような形にしておく「べき」だろうとは思ったのですが、英語をはじめとした既存のいろんなリソースに手を入れなければならなくなってしまう、というのと、そこまでしてその方式にしないと困るという実際の言語の例が僕には思いつけなかったので、ひとまず断念しました。
思うに、Rails I18nチームの基本的なポリシーとしては、
というような考え方でやっているようです。
つまり、I18nを使ってみて何か不都合があったらその人が「ギャッ」と声を上げてくれよ、というようなスタンスで進めていて、そんな形でここまでのところこれくらいの数のロケールのユーザーたちがリソースを持ち寄ってくれているわけです。
そしてそんな中で今までのところ致命的な「ギャッ」という声がまだ聞こえてこないところを見ると、意外と「主語が文章の左に来る」「主語とそれ以外は何かで区切るかもしれない」に当てはまらない言語への対応を必要としているユーザーは少ないということなのかもしれないですね。
誰か右から左に書く言語を母語とする友達とかがいたら是非とも訊いてみてほしいところですねえ。
> Yuguiさん
マジですか!? 確かに東南アジア方面の言語とかだと、もともとは区切らずに書かれていたけど最近は(植民地化後は)スペースで区切って書かれることが多い、みたいなのはある気がします。
が、この場合、ARのエラーメッセージを表示するという同一のコンテキストの中で、何かしらの要因(たとえば単数/複数とか主語の性別とか?)によって区切り方が変わる、という例はさすがにないんじゃないですかねぇ?
いや、あったらおもしろいのでむしろ是非お目にかかってみたいところですが。
Hi! HuMUjsdC