GaRuby - Ruby memo

| Next»

RubyGems 1.1.0 released

RubyGems 1.1.0が出てた(ねぼけてます。)
早速インストールしないと。

08-04-01 01:47 / Add comment

RSpecに関する記事の自分用まとめ

RSpecはTest::Unitの代わりに使えるテストフレームワーク。テストが普通の言語風に書けるのが特徴。Railsプラグインが用意されており、script/generate時にmodelやcontrollerの代わりにmodel _spec、controller_specを使うことでRSpecのテスト環境を自動生成することができる。ControllerをModelから分離した形でテストできたりするのが良い感じなので、こちらの仕様を検討してあちこちのサイトを見て回っている。中でも、るびまに連載中の「スはスペックのス」が非常によい記事なのだが、ちょうどるびま23号が出たのでそれ以外の見ているページを含めて自分用にまとめてみた。

RSpec1.1.3 Overview
RSpecの本家。英語だがチュートリアルも色々ある。
スはスペックのス 【第 1 回】(るびま)
スはスペックのス 【第 2 回】(るびま)
とりあえず読んでおくべき記事。第1回がmodel、第2回がcontrollerとview。
RSpec参考サイトまとめ(ひげろぐ)
ここからリンクをたどれば重要な記事にはたどり着けると思う。
Mocks Aren't Stubs
Ruby on Rails でのモックとスタブの作成(developerWorks Japan@IBM)
RSpecでモックとスタブ(ひげろぐ)
Rspecでコントローラのspecファイルを書く(kaeruspoon)
モックとスタブがよくわかんないので色々彷徨っている。
RSpecに待ちに待ったIntegration TestのRBehaveが追加(InfoQ)
統合テストの作成はまだ先だけども一応。
08-04-01 01:19 / Add comment

Specimenはspecimanの複数形じゃないって

Railsでは名詞の単数形と複数形は厳密に使い分けなければならないことがある。たとえばsequenceのモデルとなるクラスはSequenceで、データベースのテーブル名はsequencesだ。不規則変化の名詞もあるので、単数形と複数形を変換するためのメソッドがActiveSupportのInflectorモジュールで定義されている。複数形にするstring#pluralizeと単数形にするstring#singularizeだ。さらに、モデルとなるクラス名は大文字から始まる単数形(正確にはそれをcamelizeしたもの)なので、それを求めるためのstring#classifyメソッドもある。つまりこんな感じ:

"sequence".pluralize = "sequences"
"sequences".singularize = "sequences"
"sequence".classify = "Sequence"

舞波本で紹介されているar_fixtureプラグインを利用してfixtureを作成するdb:fixtures:saveというrakeタスクを利用して自分のデータベースを変換しようとしたら、失敗してエラーメッセージに"speciman"なる奇妙な単語が。どうやら、rakeタスク中のclassifyメソッドによってspecimenをspecimanの複数形だと思われて勝手に変換されてしまったらしい。早速実験。

"sequences".singularize = "sequences"
"sequence".singularize = "sequence"
"specimens".classify = "Specimen"
"specimen".classify = "Speciman"
"specimen".singularize = "speciman"

oops. 要するに、classifyってsingularizeしてcamelizeしてるだけなので、問題になっているのはsingularize。普通は単数形をsingularizeした時は、同じ単数形が返るのだが、specimenは語尾がmanの複数形になっていることが影響してspecimanになってしまう。railsの単数形ー複数形の変換機構が同じ語尾を持つ不規則名詞を自動的に変換するのだが、それが仇になったようだ。

こういうときのためにInflectorには、新しい不規則名詞を教えるための設定方法がある。Railsアジャイル本ではgooseーgeeseを教え込ませていた(そのままだとgoose-goosesとなる)。そこでenvironment.rbに書き加えてみる。

Inflector.inflections do |inflect|
  inflect.irregular "specimen", "specimens"
  inflect.irregular "goose", "geese"
end

なお、この項はrunブロックの外側に書くこと。でないとuninitialized constant Inflectorなるエラーが出る。そして再度実験。

"goose".pluralize = "geese"
"geese".singularize = "goose"
"specimen".singularize = "speciman"

oops. で、singularizeのソースを見てみると、

  def singularize(word)
    result = word.to_s.dup
    if inflections.uncountables.include?(result.downcase)
      result
    else
      inflections.singulars.each { |(rule, replacement)| break if result.gsub!(rule, replacement) }
      result
    end
  end
となっていて、単数化のルールはInflector::inflections.singularsにある。これを見てみると、
[/(g)eese$/i, "\\1oose"], [/(s)pecimens$/i, "\\1pecimen"] ... [(m)en$/i, "\\1an"] ...

という順番で評価されるのだから、specimenを無理矢理singularizeすれば、先ほど定義したspecimens→specimenというルールは無視され、そのあとにあるmen→manが使われるのは自明の理。つまりclassifyメソッドを改良するなりなんなりしないと話にならんと言うことか。とりあえず応急処置するとしても、何だかなあ。

08-02-27 23:59 / Add comment

Rails1.2.6 + Ruby-GetText-Package1.90.0 でrhtml処理時にエラー?

Ruby-GetText-PackageはRailsで使えるGNU GetText(Wikipedia)のようなライブラリで、データベースの多国語対応を効率化してくれる。簡単に言えば、ウェブサイトで訳すべき箇所に印を入れておくと、それを集計したセンテンス集を作ってくれて、あとはそれを誰かが訳せば、各国語版になるわけだ。GBIFやDNAバーコーディングのデータベースでも、ミーティングでは各国語へどう対応するのかが大きな問題になっている中、そこを簡単にクリアできてしまう。

ただ、ちょっと問題が。ちょっと新しいサーバでRails1.2ベースのデータベースを動かしてみようと思い。gemで最新のGetText1.90.0を入れて試してみたら、なぜかrhtmlファイルが処理されなかった。削除して一つ前のバージョンに戻したら他に修正なし(辞書ファイルもそのまま)でちゃんと動いたので、単純に仕様の問題だと思う。1.90.0はRails2.0対応版だから、rhtmlやめてhtml.erbにしろってことなのかな。

08-02-14 00:28 / Add comment

データベース構造をリセットするmigration

Railsのmigrationを使うと、データベース構造の追加修正を逐次行ったり、前のバージョンに戻したりする作業を効率よく行えるが、試行錯誤して設計しているときには、いっそのこと最初から作り直したいと思うことが多い。今までなら、いったん最初まで戻してから再構築するために、
db:migrate VERSION=0
db:migrate
とやる必要があったが、Rails2.0では
db:migrate:reset
でいけるらしい。これは便利かも。
08-02-07 01:22 / Add comment

Railsプロジェクトを操作するrubyスクリプトの実行

ちょっとしたレコードの登録・削除、動作確認などはruby/consoleを使った逐次入力が簡単だが、もう少し大がかりな操作をしたいときには、rakeタスクに書く方法と、script/runnerを使う方法があ る。後者でfoo.rbを実行したい場合には、コンソールで
ruby script/runner "load('foo.rb')"
とすればいい。ただしevalな実行環境なので遅い。
07-11-25 23:44 / Add comment

Migrationでfixture dataをセットする

テスト用のfuxtureファイルはyaml形式で書くが、リレーションシップがある場合などはテストロード用のmigrationを用意した方が楽なときがある。
class CreateFixture < ActiveRecord::Migration
def self.up
  gaist = User.create(:name=>"gaist", ...)
  data = Data.create(:user=>gaist , ...)
  ...
end
def self.down
  User.delete_all
  Data.delete_all
end
07-11-25 23:09 / Add comment

script/generateで単独のMigrationクラスを作成する

script/generateはmodelやcontrollerだけでなくmigrationも作成できる。
ruby script/generate migration add_user_column
でAddUserColumnクラスの入ったxxx_add_user_column.rbが作成される。
07-11-25 23:08 / Add comment

ヌルないし空かどうかを調べるスマートな方法

表形式のテキストを読み込んでsplitで配列に分割すると、表の末尾の空白セルはnilになってしまう。そのため、空文字列かどうかを判別するためにif s.empty?と書くとエラーになってしまうため、

s.nil? || s.empty?
s.to_s.empty?

などと書かないといけない。

RailsのActiveSupportには色々な小粒な山椒のようなメソッドがあるが、この問題の場合は、やはりActibeSupportで追加されるメソッドblank?が使える。これを使うと、

s.blank?

と書ける。Rails使わなくてもややこしいテキスト処理をしたいときについついrequireしたくなるメソッドの一つ。

07-11-25 22:42 / Add comment
| Next»

(c) Utsugi JINBO/Gaist 2001-2007

Total059805 7days562 Yesterday104 Today109 IP check in 30 min Since 2001-06-11