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

October 14, 2007 [長年日記]

[Misc] 自動生成されたブログと不思議な検索サイト

最近、本日のリンク元に、あるキーワードを元に他のブログのRSSを取り込んだ情報だけがコンテンツになっているブログと、個人ベースの検索サイト(でもそんなに流行ってないよなぁ)みたいところからのリンクが急増している。

アフェリエイトが目的なんだろうなぁ、とは思ってたのだけど、よく解説されている記事を見つけたので紹介してみる。

ワードサラダというスパムを知っていますか?

「ワードサラダ」とRSS取得による自動生成ページ&トラバなスパムたち

スパムサイト作成講座

おぉ。なにげに儲かるものなのか。じゃ、オレもやってみるかな < それはいけません(苦笑)


October 16, 2007 [長年日記]

[Misc] MS Excelのセル内で改行

ファイルから読み込んだ改行つきのテキストを1つのセルに入れ込もうとしたんだけど、改行部分に余計な"・"がついてしまって困った。

ググってみたところ、Excelのセル内って改行がCR+LFじゃなくてLFなのね。Windows 2000までだって?。XP上では起きないのかぁ。普段はXP使ってるのに気づかなかった。


October 22, 2007 [長年日記]

[Rails] STIなモデルを翻訳対象にする

Ruby-GetTextを使って、STIモデルが翻訳できないという指摘があったのですが、これはバグではなく仕様です。

具体的にはSTIなモデルで(updatepoで)テーブル名・カラム名を翻訳対象にしたいという場合は以下のように"ActiveRecord::Base"の文字列をファイル中に記述します。

 class Manager < User   # ActiveRecord::Base
 end

こうすることでManagerモデルのテーブル名・カラム名がmsgidとして抽出されるようになります。あとは通常どおり翻訳するだけです。
updatepoタスクでは、ActiveRecord向けにmsgidを抽出をする際に、そのファイル中に"ActiveRecord::Base"があればそれはActiveRecord::Baseのサブクラスのファイルである、とみなします。
したがって直接継承関係が無くても上記のように記述するわけです。

より詳しい情報はruby-gettext-MLのログを参照してください・・・・と思ってrubyforgeのMLログ見たら文字化けしてる・・・(ここでもsfmltojが必要か!? 昔は日本語通ったと思うんだけどなぁ、うーん)。一応、一月分のログなら見れるようです。こちらでsti-sampleと検索してみてください

[Rails] STIなモデルを翻訳対象にする(2)

MLが読みづらいのでここに整理しておきます。問題の指摘内容を整理すると、

「Manager < User < ActiveRecord::Baseという関係のクラスがある(Userはemailというカラムを持つ)。

rake updatepoするとUserのみが翻訳対象になり、Managerは翻訳対象にならない(1)。

User|Emailは翻訳されるけど、Manager|Emailは翻訳されない。

UserモデルにUser|Emailが定義されているんだからそのサブクラスであるManagerモデルではManager|Emailが無い場合はUser|Emailが翻訳文字列として使用されるべき(2)」

の2点です。

まず、(1)ですが、これは上で述べた方法で回避します。厳密に言えば今のrgettextが力不足で、上記のような指定をしなくても翻訳文字列として抽出できるというのがベターなのですが、なかなかうまい実装が思いつかないのが現状です。

(2)ですが、GetTextの考え方で言うと、Manager|EmailとUser|Emailは本来別の意味を持ち、分けて考えるべきです。例えば、User|Emailは「Eメールアドレス」と訳すかもしれませんが、Manager|Emailは「管理者Eメールアドレス」と訳すかもしれません。

さて、Ruby-GetText-Packageは、国際化ライブラリの一つでメッセージをローカライズするというのが主目的のライブラリです。Railsを使う人の多くは自国だけのアプリを作るためにRuby-GetText-Packageを使っている人が多いのであまり意識されないのかもしれませんが、ここで開発者以外の「翻訳者」という登場人物を考える必要があります。

翻訳者は、poファイルだけを見て(アプリの実装を知らずとも)翻訳作業を行います。その時に、開発者が(翻訳対象が減る=DRY!という観点から)poファイルにManager|Emailを無くしてしまうとすると、翻訳者は訳すどころかManager|Emailの存在すら知ることができません。もちろん、アプリケーションの内部まで追ってManager|Emailが定義されていないことを発見するという強者の翻訳者もいるかもしれませんが、私が翻訳者だったら、

「なんだか思ったとおりの訳にならないけど、まぁ、いっか、そのままで。」

と考えてそこで終わりにすると思います。せっかく適切な訳にできる余地があるのに残念な結果になってしまうかもしれません。

Emailなんだからどこの国でも訳語は1つしかないよ、と思うかもしれませんが、国によっては訳したいポイントが違うかもしれませんので、そこは開発者自身の文化的背景だけで決めたりせず、翻訳者に委ねるべきでしょう。

したがって、Ruby-GetText-Packageというライブラリとしてはアプリケーション作者がManager|Emailを用意せざるを得ない環境を作る、というのが正しい方向性で、「なかったらUser|Emailを使ってしまう」というのは目指す方向性が違う訳です。


October 24, 2007 [長年日記]

[Rails] ActiveRecord::Observer + GetTextで翻訳文字列が抽出できなくなる

という報告があったので調べてみたんだけど、これを今のrgettext側で対応するというのはちょっと厳しそう。

一応、ワークアラウンドとして以下のようなことを考えてみた。ちょっとやってみたところ動いてるみたいなんだけど、どうだろう。誰か試してみません?

# config/environment.rb
Rails::Initializer.run do |config|
   :
   :
  unless defined? GetText
    config.active_record.observers = :user_observer 
  end 
   :
   :
end
   :
   :
require 'gettext/rails'

Railsを普通に起動したときはrequire 'gettext/rails'が呼ばれる前だからGetTextが定義されていないだろう、updatepo時は先にGetTextが定義されている、という微妙な状況を判定する、というステキな回避策だ。
そういえば、ものすごい崖の上に長〜い丸太(一本のみ)の橋がかかっていて、それを渡っている最中にトリがこちらに向かって飛んできたので避けようとしたら、落っこちそうになったけど丸太にしがみついて間一髪セーフ、みたいな夢を最近見たのを思い出した。


October 25, 2007 [長年日記]

[Misc] JRuby

JRuby on RailsでRuby-GetTextを使いたい、と言う要望がちらほら、(というか一部からかなりしつこく?)くるようになった。今まで全然興味なかったから手もつけてみたことが無かったんだけど、とりあえずちょこっと触ってみることにした・・・・・ら、これなかなかのもんだね。

問題はso形式のライブラリが一切使えないこと(たぶん。おかげで、標準ライブラリの中からso系のものは根こそぎカットされてる・・・って、やり方あったら教えて!)。Ruby-GetTextではIconvとlocale_system.soが使えないのでその部分をJavaのライブラリでラップしてあげるようなコードを書く必要があると思われる。まぁRailsだけということだったらその辺をざっくりコメントアウトすれば動いちゃうんだろうけど(実際そういうパッチが送られてくるし・・・)、Ruby-GetTextはコンソールで動かしたときにローカライズされた文字列が文字化けせずに表示できる、というのがウリなんだから、どうせJRubyに対応させるんだったらそこまでやりたいよね。

ま、それはそれとして、jirbでちょっと実験。

% /usr/java/jruby/bin/jruby /usr/java/jruby/bin/jirb
irb(main):001:0> require 'java'
=> true
irb(main):002:0> locale = java.util.Locale.getDefault
=> #<Java::JavaUtil::Locale:0x1be2893 @java_object=ja_JP>
irb(main):003:0> locale.to_s
=> "ja_JP"

おぉ。簡単だ。ってかフツーにJavaでちょっとしたコードを確認したいとき、こんな感じで確認できちゃうってすげー便利かも。public static void main(String[] args)とか書かないで済むんだからなー(いつも忘れるんだよな、この文(^^;))。

[Misc] Pseudo Iconv for JRuby

とりあえず、Ruby-GetTextで使ってる文字列変換Iconv.convのJRubyでの実装はこんな感じかな。

require 'java'
 
module Iconv
  module_function
  def conv(to, from, str)
    str = java.lang.String.new(str.unpack("C*").to_java(:byte), from)
    str.getBytes(to).to_ary.pack("C*")
  end
end
 
if __FILE__ == $0
  puts  Iconv.conv("Shift_JIS", "UTF-8", "あいう")
end

とりあえず、動いたみたいだけど・・・。


October 31, 2007 [長年日記]

[Ruby] JRubyでシステムの文字コードを取得する

この前は無事JRubyでシステム(カレントユーザ)のロケールを取得できたので今日はシステム(カレントユーザ)のCharsetを取得できないか、とJava APIを探してみたら、java.nio.charset.Charsetなんて便利なクラスが。オレの時代(= Java 1.0.2 to 1.2.0)には無かったのに・・・世の中便利になったもんだ(<浦島太郎すぎ)。

$ export LANG=ja_JP.UTF-8
$ jirb
irb(main):001:0> require 'java'
=> true
irb(main):002:0> java.nio.charset.Charset.defaultCharset.name
=> "UTF-8"
 
$ export LANG=ja_JP.eucJP
$ jirb
irb(main):001:0> require 'java'
=> true
irb(main):002:0> java.nio.charset.Charset.defaultCharset.name
=> "x-euc-jp-linux"

この、UTF-8, "x-euc-jp-linux"というのは先日のPseudo Iconvでも使うことができた。
puts Iconv.conv("x-euc-jp-linux", "UTF-8", "あいう")

これで大体Ruby-GetText JRuby対応の下地は揃ったかなぁ。案外簡単そうだ。

にしても、なんだこの爽快感。JavaのAPIをirbで呼び出すのがとてつもなく気持ちがよい。Java開発がメインです、みたいな人はぜひ試してみてほしい。正直ここまで気持ちいいとは思ってなかった。

やっぱり、普段のJavaの面倒くささ(RAD起動したり、main()を始めとしていくつかの決まりごとを書いたり(RADがやってくれるけどさ)、コンパイルしたりするやつね)が一切ないのが良いんだろうなぁ。それでいて何の苦労もなくJavaの膨大なAPIが呼び出せちゃうんだからね。

[Ruby] JRubyでシステムの文字コードを取得する(2)

MS Windows XPでも試してみる。

E:\jruby-1.0\bin>jirb.bat
irb(main):001:0> require 'java'
=> true
irb(main):002:0> java.nio.charset.Charset.defaultCharset.name
=> "windows-31j"

うん。OKだね。Matz Ruby版ではwindows-31jではなくCP932が返ってくるんだけど、この違いは問題ない。(CP932という文字列をJRubyに渡しても解釈してくれないっぽい。ま、でも、Ruby-GetTextで使用する範囲なら問題ないでしょう)。