自分の興味の赴くままにIT技術系のネタを取りとめもなくメモっています。
Ruby言語やLinuxのネタが多いです。

February 02, 2006 [長年日記]

[Rails] パッチ

moriqさんに頂いたパッチを元にvalidates_length_ofの方はTracにレポートしておきました。

速攻で「んな不完全なパッチ投げるんじゃねー(意訳)」と言われてしまったので、一通りわかる範囲で見直しかけてから再度パッチを作って送り直しました。

にしてもメンドクチャイなぁ。これダメって言われたら後は知ラネ。誰か骨拾ってね(苦笑)。

.rjsの方ですが、こちらはちと取りやめにしました。というのはContent-Typeに文字コードをセットする必要があるのかどうか?というところでちょっと悩んだからです。'text/javascript; charset=utf-8'みたいな。

ググって見たところ、かぜぶろさんの「JSONとContent-Type」という興味深い記事を見つけました。

この記事によると'application/x-javascript; charset=utf-8'とすると一通りのブラウザで動作する模様です。

で、実際のところ現時点ではこの指定が正しい...のでしょうか。

元のコードはcharsetを指定していないわけで、強制的にこれを使う(つまり私のパッチを当てた状態にしてしまう)ようになってしまうと、特にEUC-JP/Shift-JISを使いたい時に困ってしまう...ような気がしたのですが実際のところどうなんでしょう。指定しなければそのJavaScriptを実行している環境の文字コードが使われるので問題ないとかいう気がしないでもないんですよね。

#なんて自信なさげな書き方なんだ、今日のオレ(苦笑)

話は戻して、「もし文字コードを指定すべき」だとすると、現在のRailsは文字コードをきちんと考慮していないので、適切に文字コードを指定するための仕組み自体を作ってあげないとまずいと思われます。なので、むしろ、前回のパッチのような状況はそのままにしておいて、Ruby-GetText-Packageで正しく文字コードを指定してあげた方が良いような気がしてきたわけです。

うーん、どうしよう。


February 07, 2006 [長年日記]

[tDiary] アクセスカウンタ表示プラグインにバグ

611行目の"counter2.log"は"counter.log"の誤りです。ここは以前のログをそのまま引き継いで使うのが正しいです。

すでにcounter-2.0.0を導入してしまった方でこのログを使っている方は、上記を修正してから、counter2.logの内容をcounter.logにコピーして使ってくださいませ。

--- old/counter.rb      2006-02-07 23:07:56.000000000 +0900
+++ counter.rb  2006-02-07 23:02:46.000000000 +0900
@@ -266,7 +266,7 @@
   
     def log
       if @newestday
-       open(File.join(@path, "counter2.log"), "a") do |io|
+       open(File.join(@path, "counter.log"), "a") do |io|
          io.print @newestday, " : ", @all, ",", @today, ",", @yesterday, "\n"
        end
        save("counter2.dat." + @newestday.wday.to_s)


February 08, 2006 [長年日記]

[Ruby] Ruby-GetText-Package見直し中

えいやーで実装してしまっていたところを徐々に修正中。ひとまず、Locale周りを見直し、Locale::Objectクラスを追加、なるべくシステム固有の部分を排除するようにした。しかしながらこの辺の機種依存ってホント困るなぁ。うまく正規化できないや。

そうそう、最近、RoR界でもRuby-GetText-Packageを使った実装をちらちら見かけることができるようになった。Hieraki2のブランチでも試験的に採用された模様だし。これは本採用されるといいなぁ。

InstikiのI18Nのページで、"But given the speed of developpement of Instiki, it would be hard to keep the translations in sync without something like gettext support" とDenisさんが言っているけど、メンテナンスツールが無い状態でL10nをサポートし続けるのってめちゃくちゃ大変ってことに気づいている人がまだまだ少ない気がする。自動生成されるだけじゃダメで、マージまでしてくれないと。じゃなきゃ抜けがないようにするのって大変なんすよ。

あと、よく言われるんだけど、Ruby-GetText-PackageがIconvやRaccに依存してると思っている人がまだ多いみたいね。

Iconvについては、もともとpoファイルを出力する文字コードに合わせて記述すれば特に不要だし(Iconvが見つからない場合は元の文字列を返すようになっている)、RaccはRubyに標準添付されているランタイム以外(Ruby-GetText-Package自身の開発時以外)は不要になったんだよね(1.0.0から)。

だから、依存するライブラリは今のところ意識するようなものは無いんだけどな。

それから、GlobalizeにあってRuby-GetText-Packageに無い機能としてデータベースのテーブルをローカライズできるようにっていう要望をたまにもらうんだよね。

でも、テーブルのローカライズっていまいち用途がわかんない。

Globalizeの場合はあるテーブルのあるカラムに英語とそれ以外の言語を追加で記述していくような仕組みを持ってるんだけど、それってGlobalize自身の翻訳(つまりメッセージカタログとしての使用)以外に用途があるのかなぁ(認識間違いがあればご指摘プリーズ!)。

むしろ、そのテーブルのレコード毎に言語を指定、というのなら何となくニーズがあるような気はする。というかそういう要望をもらったので、なるほどそういう使い方もあるのかぁ、と思ったぐらいなんだけど。

そっちの方は、

act_as_localize(:accept_language => ["en", "ja"], 
                 :default_language => "en")

みたいな感じのを作ると便利なのかな。ここで設定したテーブルは"lang"というカラムが(できれば自動で)追加されて、ユーザからのリクエストがLocale.getを使って"ja"に該当すれば"ja"を、それ以外の場合は"en"を指定するようにして、かつ、検索する場合のwhere句にはデフォルトで"lang = 'ja' "が追加されると言う感じ。
誰か実装しません?(また他力本願だよ(苦笑))


February 09, 2006 [長年日記]

[Misc] メタサーチComentonはリファラスパムを出してる?

なんか、ずーっと前から気になってたんだけど、なぜか、メタサーチComentonから、ほぼ毎日、検索リファラが飛んでくる。しかも、必ず、ruweexという私がものすごく昔に開発して今は全くメンテナンスもしていないツール(とその元ツールであるweex)をキーワードにしてくる。

他の検索エンジンからの検索語の割合を見ても、ruweexで検索してくるのはかなり希なのでおかしいなぁ、と思ってたんだよね。

で、ここ数日、このComentonのサイト自身が「休止中」となって検索ができなくなっていることに気づいた。でも、やっぱり、リファラが飛んでくる。

昨日も飛んできたし。なんか変だなぁ。これってやっぱりリファラスパムの一種?

[Rails] act_as_localize(2)

昨日、カラム毎にローカライズできる仕組みをどんな場面で使うのか用途がわかんない、と書いたけど、一つ思いついた。

多国籍企業で1つのデータベースを使う。Nameの欄には英語で、「氏名」の欄にはローカライズされた言語を使う。で、言語用のlangカラムを持っていて、通常は自分の国のものしか表示されない。

って、どうかな?でも、このケースでもName欄自体を複数の言語化はしないよなぁ。


February 12, 2006 [長年日記]

[Ruby] 風博士 0.3.5

なにやらRubyで風博士を拡張できるんだそうです。すごい。

GObject使うところではRuby-GNOME2も関係してるのかな。

どうでもいいけど、「かぜはかせ」の変換時に、最初に「風邪博士」になってしまったのを見て、ついうっかり笑ってしまいました。

本日のツッコミ(全4件) [ツッコミを入れる]

Before...

むとう [おぉ、そうでしたか。 それならruby-gnome2-devel-enあたりでもアナウンスしてみてはいかがでしょうか..]

kou [頑張ってみました. < ruby-gnome2-devel-en # ruby-talkに投げるくらいの元気はないで..]

むとう [ありがとうございます! GLib::Log.set_log_domain()の方、もしかしたらGCのタイミングによ..]


February 13, 2006 [長年日記]

[Ruby-GNOME2] Mr. Guid

Ruby GUIデバッガだそうです。デバッガとしてはすでにかなりの完成度と見ましたがどうでしょうか(使ってないで言うヤツ(^^;))。


February 15, 2006 [長年日記]

[Ruby-GNOME2] Tomgirl

TomboyのRuby-GNOME2版だそうです。でも、Tomって男性の名前ぢゃ・・・。


February 18, 2006 [長年日記]

[Ruby-GNOME2] Fantasdic

Nihongo BenkyoのMathieuによる辞書アプリ(DICTクライアント)。Screenshotを見るとなかなかよさげ。Wikipediaの情報とかも見れるらしい。

Nihogo Benkyoの機能はほとんど持ってるそうなので、そっちは開発やめるかもしれない、とのこと。



February 23, 2006 [長年日記]

[Ruby] Ruby-GetText-Package-1.2.0

リリースしました。

今まで動けばイイやーってな感じで多少適当に実装してしまっていた部分をリファクタリングしていこうということで、今回はその第1弾としてLocale周りを再実装しました。デグってたらごめんなさい。

具体的には、今まではsetlocale()をベースとしたロケールIDと文字コードを取得するような実装だったものを、Locale::Objectというオブジェクトがロケール情報(ロケールIDと文字コード)を管理するようになりました。

これによりシステム依存部分をだいぶ抽象化できたと思います。

次はTextDomainかなぁ。道は遠い。


February 24, 2006 [長年日記]

[Rails] ロケールによるテンプレート切り替え

航海日誌さん経由で知ったのですが、「Rails勉強会@東京 第3回」でRailsの国際化について話があって、Ruby-GetText-Packageも議題に上げて頂いたようですね。ありがとうございました。ってか、国際化ってそんなにホットな話題になってるんでしょうか。なんかそれ自体がちょっと意外だったりしますが。

さて、いろいろとリンクを辿ってYuguiさんの議事録を読まさせていただいた(議事録を残して頂きありがとうございました)のですが、「ロケールによるテンプレート切り替え」「文言単位での対照訳」のどちらを使うのか悩まれている方がいらっしゃるようですね。

なので、それについて私の意見をちょっと書いてみようと思います。まぁ、Ruby-GetText-Packageの開発者なので若干偏っているとは思いますが(結論は見えてますしね(苦笑))。

まず、「ロケールによるテンプレート切り替え」ですが、私はこれには否定的な考えです。議事録では利点として

「国際化対応というのは異なる文化慣習への対応でもあるから、単なる文言の修正では済まないこともある。テンプレートごと差し替えてしまえばそういうケースでも対応が楽。」

とあります。これは、真かもしれません。しかし、実際のアプリ開発を考えると

「翻訳者が開発者も兼ねておりしかもずっと開発体制を維持できる」

か、あるいは、

「テンプレートはもう仕様変更無し」

の2つの場合でしか成功しないと思います。特にモリモリ開発中のアプリでは大変です。

例えば、あなたがアプリの開発者だとしましょう。ある画面(テンプレート)にボタンとメッセージを追加したとします。あなたは日本語のテンプレートと、英語のテンプレート(あと、英語っぽいテンプレート)には手を入れることができるでしょう。でも、divタグやらなにやらが変更されているテンプレートについてはあなたが手を入れることはできないでしょう。なので翻訳者に「これこれこういう機能を実装したから、それをテンプレートに反映してね」とお願いしなければなりません。そして、その翻訳者(兼開発者)はその機能を十分に把握した上で適切にテンプレートに反映させる必要があります。

これは本当に骨の折れる作業です。しかも、修正されたテンプレートが正しく修正されたのか、開発者自身が判断つかないという事態になりかねません。「テンプレートごと差し替えてしまえばそういうケースでも対応が楽。」と言う見解にはやはりNOと言わざるを得ません。

さて、開発が進んだところで、翻訳者が開発を続けられなくなった場合どうでしょうか。きっと(古くなってしまった)言語テンプレートは削除せざるを得ないでしょう。

これに対し「文言単位での対照訳」にしておけばどうでしょうか。翻訳者はテンプレート書き換えに比べて(自由度が減るため)負荷が減ります。さらにRuby-GetText-Packageを使っていれば、未翻訳であってもその部分が英語で表示されるだけで済むため、多少無理はあってもその言語を残せる可能性が高まります。その言語で使いたいユーザにとっては少しでも自分の読める言語になっている方が良いと思う人が多いのではないでしょうか。

したがって、私としては、なるべく開発者自身が把握できる範囲でViewの実装までして、文言だけ翻訳してもらう、というスタイル、(まぁ、つまりGetTextのアプローチなわけですが)を強くオススメします。

GetTextの歴史を考えても、多くのGUIアプリはこれで十分なはずです。

とはいえ。どーしてもテンプレート切り換えをしたい場合もあるでしょう。ターゲットが「英語と日本語だけ。自分が全部やるから問題ない!」という場合などはその方が効率的かもしれません。

Rails MLでは同じくYuguiさんがプラグインで実装されていらっしゃいますが、これにさらにRuby-GetText-Packageを組み合わせるとロケールの選択がRuby-GetText-Packageと同等になるため、便利だと思います&ちょっとだけ実装が簡単になると思います。

#次のRuby-GetText-Packageではこの機能を導入しちゃおうかしら。ライブラリとしてはどちらの機能も提供する、というのはアリだよね。

--vendor/localize_templates/init.rb:
 
ActionController::Base.class_eval do
  alias render_file_without_locale render_file
  private :render_file_without_locale
 
  def render_file_with_locale(template_path, status = nil, use_full_path = false, locals = {})
    locale = GetText.locale
    [locale.to_s, locale.language].each do |v|
      localized_path = template_path + "_" + v
      return render_file_without_locale(localized_path, status, use_full_path, locals) if template_exists? localized_path
    end
    render_file_without_locale(template_path, status, use_full_path, locals)
  end
  alias render_file render_file_with_locale
end

こんな感じ。require 'gettext/rails'とinit_gettextは別途必要です。って、試してませんので動かなかったらごめんなさい(苦笑)

話はちょっとズレますが、Rails MLってローカライズ周りのネタって結構話出てるんですかね。Rails ML入った方が良いのかなぁ。ってこれ以上ML入るとメールがパンクしそうでなかなか踏み入れられないものがあるのですが(苦笑)。

おっと、忘れてた。(ローカライズとは別に)User-Agent毎にテンプレートファイルを切り替える目的でrender_fileの挿げ替えというのは良いアイデアだと思います。


February 27, 2006 [長年日記]

[Rails] ロケールによるテンプレート切り替え2

ロケールによるテンプレート切り替えについて、Yuguiさんがご自身の関わられているRailsJSPを使ったアプリの国際化作業について紹介されています。確かに企業ベースで開発する場合、各国々でそのお国事情に合わせたViewが(翻訳というものを超えて)必要になるというのは理解できました。特にBtoC周りでは多く求められそうですね。

私の「ロケールによるテンプレート切り替え」は、どちらかというと個人ベースでオープンソースとして開発するアプリをイメージして書いたものです。なので企業ベースで多国籍をサポートできる開発者・翻訳者をアサインできる環境が整いつつあるのであれば、ロケールによるテンプレート切り替えというニーズが今よりも高くなることはYuguiさんの事例からも予想できますね。

ということで、先日のテンプレート切り替え機能はRuby-GetText-Packageに取り込む方向で考えようと思います。ちょっと他にやりたいことがあるので多少優先度は落としますが。

[Rails] jascaffold vs gettext

iR3さんの日記で、jascaffoldかgettextかということを書かれていたのでコメントを残させていただきました。その後に、jascaffoldの実装を斜め読みしてみたのですが、jascaffoldって日本語以外もサポート可能な作りになっているようですね(今のところ日本語と英語のみのようですが)。きちんと確認もせずに誤ったコメントを残してしまいすみませんでした。

んで、ちょっとだけですがjascaffoldを試してみました。ローカライズの部分ってconfig/localize.ymlを決め打ちで読み込んでるので、実行時に変更はできない、つまり、アプリの1カ国語化(テンプレートは英語と日本語が用意されている)ですよね。

#間違えていたらご指摘くださいませ。

対するgettextの方は、実行時の多国語化が目的になるのでちょっと比較の対象にするのは難しいんじゃないかと思います。1カ国語をターゲットとするならjascaffoldで良いんじゃないでしょうか。

現時点でのgettextの優位点をあげさせて頂くとすれば、modelのローカライズ(validationメッセージも含む)とrake updatepoコマンドによるローカライズ対象文字列の自動抽出・マージ機能、といったところでしょうか。スペジェネではサポートされてる機能もあるかもしれませんがそちらは見てないので・・・・・・とても眠いので今日はこの辺で。

#個人的にはjascaffoldがgettextベースになってくれるととっても嬉しいんですけどね。

本日のツッコミ(全3件) [ツッコミを入れる]

Yugui [あ、誤解を招く表現ですみません。事例として背景を挙げたのはJSPのケースでして。うちではまだ国際化が必要なアプリケー..]

むとう [あぁ、そうでしたか。私こそ誤解してすみませんでした(修正しておきました)。 ご指摘の通り、確かにテンプレート切り替..]

むとう [おっと忘れてた。rake updateは我ながら便利だと思います。merge自体もかなり高度にやってもらえますし、も..]


February 28, 2006 [長年日記]

[Misc] リファラスパム

久しぶりにやられた。うきーっ!

[Rails] Ruby-GetText-Packageでエラー画面のメッセージを変更する

昨日の件で、Special Generator、jascaffoldをもうちょっと勉強しようと思っていたら、ちょうど、樂水開発日記さん経由で「jascaffold 勝手にまとめページ」を知りました。おっ、これは・・・って、またgettextが話題になってますね(苦笑)。

ちょっと回答部分で誤解もあるようなのでここでフォローをしたいと思います。

#守護霊の忠告に従って(笑)私自身は人様のWikiに何かを書くということはしません。どなたか気になった方がいましたらリンクでも張って頂ければ幸いです。

で、誤解かと思われる部分は「modelのクラスに直接かかれたvalidateなどの文字列は簡単には変更できません。」のところです。私自身が誤解してるとアレですが、ここでは「validateのメッセージを簡単に変更できない」ことを指していると受け取りました。が、そうだとするとそれは誤解です。そうでなければ私の誤解なのでこの後の文章は無駄に・・・(汗)。

Ruby-GetText-Packageでは、validation系メッセージがデフォルトでローカライズ(日本の場合は日本語化)されるだけでなく、オリジナルのRails同様、ユーザがvalidationメッセージを指定できますし、しかも、メッセージのタイトルも変更できます。

#この点では実はオリジナルのRailsより柔軟です。

そこで、Ruby-GetText-Packageに添付されるblogアプリケーションのapp/models/article.rbを例にしてその使用方法をご紹介します。

class Article < ActiveRecord::Base
  # With validation messages.
  validates_presence_of :title, :message => "%{fn}は空じゃダメだよ!"
  validates_length_of :description, :minimum => 10, :message => "が短すぎッス。%d文字以上でお願い。"
  # Title
  set_error_message_title("%{record}にエラーみっけ。", "%{record}に%{num}個エラーあるよ")
  set_error_message_explanation("次のフィールドにエラーあるよ:", "次のフィールドたちがエラーだよ:")
end

こんだけです。%{fn}がフィールド名、%{record}にはテーブル名、%dは数が入ります。%{fn}を省略するとローカライズされた文字の先頭にフィールド名が挿入されます(Rails本体との互換性を保つためにこういう仕様になっています)

結果は以下のようになります。まず、エラーが2つあるとき。

Railsのエラーメッセージを変更する(1)

次に、エラーが1つの時。

Railsのエラーメッセージを変更する(2)

日本語だとわざわざ単数形と複数形にわけるのが面倒くさいかもしれないけど、海外だとこういうときの複数形は大切なので複数形と単数形で異なる出力になってます。

ちなみに上記の例では必ず日本語が表示されますが(当然と言えば当然ですが)、_()で囲って英語を使うようにすればそのまま多言語化できます(これも当然と言えば当然?)。