2011-01-11
■ [rails] Railsプラグインの探し方
Railsは進化が速いので、昔定番だったプラグインでも今はもっといいのが出てることがままある。
例:
- RDBで木構造を扱いたい
- acts_as_treeというのが定番だっけ
- http://ruby-toolbox.com/projects.html からacts_as_treeを探してクリック
- 木構造を扱うライブラリの一覧が人気順に見れる
- awesome_nested_setが一位、だけどLast commit: about a year ago なのでRails3は対応してない可能性もある
- http://railsplugins.org で、Rails3対応かどうかチェックしてみる
- http://railsplugins.org/plugins/197-awesome-nested-set (今回は残念ながら情報なし…)
- 2位のancestryは最終コミットが最近なので、Rails3も大丈夫そう
という流れでancestryに至ると。
2011-01-13
■ [git][ruby] github gemからgit-hub gemに乗り換えた
自作のプロジェクトをgithubで公開するとき、わざわざWeb画面からリポジトリを新規作成していませんか?hubコマンドをインストールすれば、「hub create」一発でできますよ。
githubのリポジトリをコマンドラインから操作するのにgithubコマンド(github gem)を使っていたのだが、ある時からcreate-from-localが動かなくなってたり、Ruby 1.9に未だに対応してなかったりするので おかしいなと思ったら、もっと新しいツールがあったらしい。
$ gem install git-hub
でインストールすると、hubというコマンドが使えるようになる。例えば現在のディレクトリからgithubリポジトリを新規作成するには
$ hub create
でいける (ディレクトリ名がリポジトリ名になります)。他にもhub forkでgithub上のリポジトリを簡単にforkできたりとか。
githubコマンドを使ってなかった人は、先にgithubのログイン情報を登録する必要あり。<APIトークン>は https://github.com/account にある。
$ git config --global github.user <ユーザ名> $ git config --global github.token <APIトークン>
hubコマンドは、自分が知らないオプションが来たときはgitコマンドにそのまま渡すので、gitコマンドを拡張するツールとして使うこともできる。つまり、
$ alias git=hub
みたいに定義すれば、git addやgit commitに加えてgit createやgit forkが使えるようになるというわけ。
作者はこの使い方を推奨してるみたいだけど、個人的にはhubコマンドのままでいいかな。
2011-01-19
■ [ruby] open-uriでUTF-8でないページを取得するときの注意
Ruby標準添付のopen-uriライブラリを使うと、HTMLを簡単に取得することができる。
irb> require 'open-uri' irb> url = "http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-dev/43008" irb> html = open(url).read
このとき、文字コードがUTF-8でないことが分かっているなら、第二引数でエンコーディング名を指定しておいた方が良いだろう。(あ、ここからはRuby 1.9の話です。)
irb> html = open(url, "r:euc-jp").read
読んだあとは、String#encodeでUTF-8に変換することができる。
irb> html = open(url, "r:euc-jp").read.encode("utf-8")
文字化け対策
ところで、このコードは例外を投げる可能性がある。例えば http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-dev/43039 のように文字化け(EUC-JPでないバイト列)を含んだものをUTF-8にしようとすると、
Encoding::UndefinedConversionError: "\xAE\xE6" from EUC-JP to UTF-8
という例外が発生する。普段はちゃんと動いてたプログラムが、入力によって突然死するのは避けたいところだ。
で、例外なので、begin-rescueでキャッチしてやることも可能だが、もっと簡単な方法がある。String#encodeにオプションを渡すと、不正なバイト列の扱いを指定することができる。例えば以下のようにすると、不正なバイト列や変換が未定義のバイト列は適当な記号で置き換えられる。
irb> html = open(url, "r:euc-jp").read.encode("utf-8", :invalid => :replace, :undef => :replace)
というわけで、文字化けには注意しようという話でした。
余談1 : 安らかに眠れ、Hashロケット
ちなみにRuby 1.9では、=>なんていう指負担の大きい文字列を入力しなくてすむ文法が用意された。
irb> html = open(url, "r:euc-jp").read.encode("utf-8", invalid: :replace, undef: :replace)
余談2 : Railsではreadの時点で例外が起きる
irb上とRailsアプリ内では、例外の起きるタイミングが違う。(というのが実は本題)
Rails(3.0.3)はEncoding.default_internalをUTF-8に設定するため、readしたときにEUC-JPからUTF-8への変換が行われる。それは便利だ、と思うかも知れないが、上の例でいうと encodeしたときではなく、readした段階で例外が発生するので、
open(url, "r:euc-jp").read
がUndefinedConversionErrorを吐く可能性があるわけだ。
解決法としては、一端binary(ASCII-8BIT)として読み込んでやるという方法がある。
open(url, "r:binary").read.encode("utf-8", "euc-jp", invalid: :replace, undef: :replace)
encode(enc, invalid: :replace, undef: :replace)は、safe_encodeみたいな別名があってもいい気がしてきましたね。
2011-01-28
■ [rails] Railsのテストを高速化するやつ
ちょっと調べた。導入はわりと簡単なので試してみると良いです。
spork
Railsをロード済みのテストサーバを立てることによって、テストの起動時間を短縮する。
Rails 3対応。Rails 2の場合はspork 0.8.xを試せと書いてある。
テストフレームワークはRSpec、Cucumberに対応。Test::Unitを使う場合は https://github.com/timcharper/spork-testunit を入れる(ただし1.9未対応…)。
parallel_tests
テストを複数のプロセスで実行することによって、テストの実行時間を短縮する。 (テストの起動時間は変わらない。テスト数が多い場合に有効)
Rails 2/3、RSpec、Cucumber、Test::Unitに対応。