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

February 08, 2004

[Misc] あー

何もやる気が起きない....。久しぶりだ、ここまでダメなのは...。

[Misc] UNIX USER 2004.3

かずひこさん、村田さん、しげゆきさんによるフォント徹底解剖を読む。あまりこの辺をきちんと理解しようと思ったことがなかったので、とても勉強になる。

っと途中で何気なくRuby-GNOME2のサンプルが。たむらさんの記事といい、意外なところで脇役として出てくるのでびっくりする。Ruby-GNOME2が出てる雑誌は記念買いしてるんだけど、今回はあやうく買い損ねるところだった(^^;)。

でも、こういった他の記事の合間にさも普通のことのようにRubyとRuby-GNOME2の記事が出てくるのはとてもありがたいことだと思う。

とりあげてくださったお三方に感謝です。

ちょっとだけやる気が復活してきた。明日からがんばろう。

#せめて金曜日に読んでおけば土日もう少し何かできたかもしれないなぁ(^^;)。

[Ruby-GNOME2] ダイアログの書き方

先のUNIX USERでRuby-GNOME2のサンプルとしてあげられてるのが以下のようなスクリプトだ。

require 'gtk2'
Gtk.init
fontsel = Gtk::FontSelectionDialog.new("gtkfontsel").show
fontsel.signal_connect("delete-event"){ Gtk.main_quit }
fontsel.cancel_button.signal_connect("clicked"){ Gtk.main_quit }
fontsel.ok_button.signal_connect("clicked") do
  puts fontsel.font_selection.font_name
  Gtk.main_quit
end
Gtk.main

これはこれで良いんだけど、実はGTK+-2.0系からのGtk::Dialog#runを使うともっと短く簡潔に書くことができる。Gtk.mainもいらない。

require 'gtk2'
Gtk.init
fontsel = Gtk::FontSelectionDialog.new("gtkfontsel")
case fontsel.run
when Gtk::Dialog::RESPONSE_OK
  puts fontsel.font_name
end
#fontsel.destroy  #厳密には必要なんだけどこのくらいのサンプルの場合は無くても良いかな

このやり方は、「ボタンをクリックすると必ずウインドウを閉じる」という場合に有効だ。

とはいえ「OKボタンをクリックしたときウインドウを閉じない」場合は、このGtk::Dialog#runを使うやり方ではなくUNIX USERの例が必要になるかな。

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

かずひこ [ふふふ。やっと気がつきましたか。 「ページ数オーバーです」と言われたときに、そこだけは死守したのです。v(--)]

むとぽん [おー、死守していただいたんですね。ありがとうございます。]


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 08, 2007

[Rails] Rails のためのものぐさな Web アプリケーションの国際化手法 by Secondlifeさん

ローカライズの主言語に日本語を使うことで英語が苦手な人でも無理無くアプリを国際化(を前提とした開発が)できるよという話。「最初は日本語で開発、とりあえず、メッセージは_("")で囲い後で英語リソースを用意する」という開発スタイルは、思考が(英語に翻訳するという)余計なことで妨げられない分、ストレスが少なくて良いよね。個人(や企業)でサポートする全ての言語を自前で用意する場合、主言語が英語以外でも問題ないしこの方法はアリだと思う。

注意点としては、アプリケーション本体とmsgidの文字コードをあわせる必要がある、ということかな。msgidは文字コード変換を適用していないからね。

それから、はてなユーザ以外はコメントを残せないそうなのでここに書いちゃうけど、GetText.locale の値が HTTP_ACCEPT_LANGUAGE のが適用されなくなる?という件については、手元の環境では再現しなかった(after_init_gettextを使わなくてもブラウザの言語設定をenにしたらfoo_en.rhtmlが読み込まれた)。なぜだろう。あ、でも試したのはCVS版だからリリースバージョンでは再現するのかな。

[Rails] Rails のためのものぐさな Web アプリケーションの国際化手法 (2)

上でちょっと触れたけど、全ての言語を自前で用意する、というのが難しい場合(多くのOSSな開発はこっちなのではないかな)、msgidは英語で書いた方が良い。いや、書くべきだ。インターネットの世界では日本語を読み書きできる人に比べて英語を読み書きできる人の方が多く、その方がより協力者を得やすいからね。

しかし、Secondlifeさんの方法も捨てがたい。

そこで、ひとまずはSecondlifeさんの手順通り進め、日本語が主言語、英語のリソースを用意するというところまで作ってしまい、ある程度安定してきたら、一括して日本語部分を英語に変換してしまうというのはどうだろう?・・・と思ってそんなスクリプトを書いてみた。眠いので書きなぐり。うぅ、汚い。けど眠気には勝てないや(苦笑)。

$KCODE = "U"
require 'gettext/mo'
 
@mo = MOFile.open("locale/en/LC_MESSAGES/example.mo") #アプリ毎に変更する
def convert(path)
  return unless File.file? path
  puts "target = #{path}"
  data = IO.read(path)
  bak = data.dup
  @mo.each do |key, value|
    data.gsub!(Regexp.new(Regexp.quote(key)), value) if key.size > 0
  end
  unless bak == data
    open(path + ".bak", "w"){|f| f.write bak}
    open(path, "w"){|f| f.write data}
  end
end
 
Dir.glob("app/**/*") do |path|
  convert(path)
end
 
File.open("ja.po", "w") do |out|
  @mo.each do |key, value|
    if key.size > 0
      out.puts %Q[msgid "#{value}"]
      out.puts %Q[msgstr "#{key}"]
      out.puts
    end
  end
end

実行するとapp配下で該当する日本語文字列を英語に置換していく。んでもって最後にカレントディレクトリにja.poという名前の日本語poファイルの雛型を抽出してくれる、という感じ。
ちょっと特殊な文字とか改行とか含んでいるだけでダメだなこりゃ。コメント部分に該当する文字列があるだけでそちらも変換してしまう。まぁ、Proof of conceptということで。もうちょっとがんばれば、ja.poもただ雛型を生成するだけではなく、きちんとpo/ja/example.poを生成するようにもできるね。
というわけで誰かまともな実装してくれる人いません?(ホント、最近、こればっかりだな、オレ(苦笑))

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

Before...

むとう [なるほど。 ブラウザを2つというのは違うインスタンス(2種類のWWWブラウザ)を起動して、ということですよね? #例..]

secondlife [> ブラウザを2つというのは違うインスタンス(2種類のWWWブラウザ)を起動して、ということですよね? > #例え..]

むとう [りょうかいです。]


更新 設定