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

July 30, 2004

[Ruby] RPA-base

Ruby Production Archiveだそうだ。rpmみたいなもの?

なんか作者の人から、ObjectPoolをrpa化しないかい?っていう誘いのメールが来た(なぜRuby-GetText-PackageではなくObjectPoolなんだ...(-o-;))。なんかメンドッチーのでとりあえず無視。ちなみにGemsとやらとは違うの?誰かその辺のことまとめてる人いないかな〜、日本語で(夏なので英語読むのが辛くなって来てる(^^;))。

ところで、rpa化する場合、以下のようなinstall.rbを書くらしい。

require 'rpa/install'
 
class Install_objectpool < RPA::Install::PureRubyLibrary
    name "objectpool"
    version "0.2.0-1"
    classification Library.Development
    build do
        installdocs %w[COPYING COPYING.ja ChangeLog README]
        installdocs "docs/html/en", "html/en", true
        installdocs "docs/html/ja", "html/ja", true
        installtests %w[test.rb]
        installmodules %w[objectpool.rb]
    end
    description <<EOF
Enables sharing of instantiated objects.
 
ObjectPool provides a mechanism for pooling objects and resources.
EOF
end

なんか、青木さんのsetup.rbに体が馴染んでしまったオレ的には、installxxxxとかいう感じでインストール対象を指定してること自体が面倒臭い。ホント、ディレクトリ構造固定で良いじゃん!って思う。

パッケージ管理するなら、青木さんのsetup.rbはそのままで、ルートディレクトリにXMLファイル(YAMLでも良いけど)を作って上記のような情報を書くだけでうまくやってくれるものにしてくれないかなー。

っつーか、別にRuby専用のものを作らずともrpmとかでいいじゃん、とか思うんだけどなぁ。ダメ?

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

MoonWolf [うちにも来ました。>RPA やっぱdebとかrpmでいいじゃん?とか思っちゃいますよね。]

むとぽん [片っ端からメールしてるんでしょうねぇ。MoonWolfさんところはたくさん来たんじゃないですか?(^^;)]


July 30, 2005

[Ruby-GNOME2] 64bit環境

今回の件をレポートしてくれたJoeと何回かメールでやりとりしたところ、彼が彼のマシンにアカウント作って提供してくれた。ラッキー。ssh -X ってやるとXプロトコルも通せるのね。知らんかった。

そんなわけで、一通り(といっても、彼のマシンに入っていなかった一部ライブラリは確認できていないんだけど)のライブラリについては、サンプルの動作確認をすることができた。あと、rbbrも。

何点か不具合がわかったけど、ほとんどkouさんの指摘範囲での修正で済んだので良かった良かった。網羅はできてないけどそれは追々直していくしかないよね。

これからもアカウント使わせてくれると嬉しいのだけどどうなることやら。

とは言ってもさすがにXが遅いんだよなぁ。でもコンパイルは異様に早かった。うらやますぃ。やっぱり64bitマシン欲しくなってきたなぁ。

さて、リリース準備に取りかかりますか。明日から(苦笑)。


July 30, 2006

[Ruby] bindtextdomain_to(klass, domainname)という考え方

Railsやってて気づかされた点でまだ悩んでいる点があるので書いて整理しようと思う。

オレの今までのRuby-GetTextでの想定というのは、「そのクラス・モジュールが持つ静的なロケール情報をそのクラス・モジュール自身がローカライズできるような機能を提供する」というもの。

例えば、以下のような例。話を単純化するため、「ライブラリ開発者=ローカライズ対象のライブラリを開発する人」「アプリ開発者=そのライブラリを使って開発する人」の二人の登場人物で考える。

class Test
  include GetText
  bindtextdomain("test")
  def test
    _("Foo")
  end
end

上記は、ライブラリ開発者が作るライブラリ。Testクラス自身がローカライズすべき静的な文字列を持ち、それをTestクラスの開発者自身が明示的に指定し、po/moファイル等も提供する、というスタイルだ。

しかし、その枠にはまらないライブラリが出てきた。例えば、ActiveRecord。ActiveRecordはvalidation系のメッセージは上記の通りで問題ないんだけれども、各テーブルのカラムのローカライズは、アプリケーション開発者が行うはずだし、ライブラリのテキストドメインとは別にアプリ用のドメインを持ちたい、という話になる。

といっても、ActiveRecordはサブクラスをアプリケーション開発者が作るので、元々の発想ベースで行くと、ActiveRecordのサブクラス(例:ActiveRecordApp)を一つ作って、そこでbindtextdomain("app")し、他のサブクラス立ちはActiveRecordAppを継承するようにすれば良い。
んだけども・・・・

おっと時間がなくなっちゃった。あとは続く!(というか上記も書き直す可能性ありです。

[Ruby] bindtextdomain_to(klass, domainname)という考え方(2)

ということで続き。ふぅ、今日は楽しかった。いや、そりゃ書く場所が違うな。

まずは、上での話をもうちょっと補足する。上記のTestの例で言うと、Testクラスはライブラリとして提供されるクラスで、アプリケーション開発者側は以下のようにサブクラスを書いてそれを使う。

class AbstractApp < Test
  include GetText
  bindtextdomain "app"
  def foo
    _("foo")
  end
end

サブクラスが複数ある場合、上記をアプリに1つ作って残りはそのサブクラスにする。厳密に言うと、当初(0.x台)のRuby-GetTextを開発していた当時はサブクラス毎にbindtextdomainするべき、という考えだったんだけど、DRYの法則に反するYO!と言う声が聞こえたような気がするのでその案は撤回した。

class ConcreteApp < AbstractApp
  def bar
    _("bar")
  end
end

これがオレが今までに考えていた方法。

でも、じゃぁ、Testクラスを使うために毎回AbstractAppを書かなければいけないのかというと、それも広義な意味ではDRYじゃないよね。
Rubyの場合は幸い既存のクラスに機能を追加できるのでAbstractAppを書かないこともできる。それがbindtextdomain_to。

GetText.bindtextdomain_to(Test, "app")
  
class ConcreteApp < Test
  def bar
    _("bar")
  end
end

GetText.bindtextdomain_toの実装は以下のような感じ。

def bindtextdomain_to(klass, domainname, opts = {}) 
  klass.module_eval {
    include GetText
    bindtextdomain(domainname, opts)
  }
end 

実はほとんど同じ実装がすでにgettext/rails.rbにあったりする。なので、Railsの場合はinit_gettextを呼び出すだけで、使用する全てのモジュール/クラスで一つのテキストドメインを使うことができるようにしている。でも、その時はこういうことを整理して実装したわけではなかったんだよね。

うーん、一般化する必要はあるのかないのか・・・。Rails的にはあった方がよさげなんだけどなー。なやますぃ。

[Rails] init_gettextにブロックを使えるように

これも忘れないように書いておこう。

前述したbindtextdomain_toを用意したとして、今度はそれを呼び出すタイミングをどうするかという問題が残る。

RailsではWWWからアクセスされる度にロケールが変わるので以下のように書くことはできない。

class ApplicationController < ActionController::Base
  bindtextdomain_to(Foo, "blog")
  init_gettext "blog"
end

厳密に言うと、init_gettext内部でset_locale_allを呼び出してロケールをいったんリセットしてあげれば良いんだけど、それやると実行コストが無駄にかかるような気がする(未測定だけどね)ので現状はそうしていない。

そこで、init_gettextでブロックを受け付けるようにしてあげることを考えた。

class ApplicationController < ActionController::Base
  init_gettext("blog"){ |name|
    bindtextdomain_to(Foo, name)
  }
end

これなら、bindtextdomain目的以外でも「ロケールが決定したあとに実行したい初期化」というのをまとめて行うことができる・・・。
と今日のところは考えてみたんだけど、どうだろう。

にしても今日は結局考えがうまくまとまらなかったな。また来週じっくりと考えることとするか。