IT・技術研修ならCTC教育サービス

サイト内検索 企業情報 サイトマップ

研修コース検索

コラム

Ruby & Rails

CTC 教育サービス

 [IT研修]注目キーワード   Python  UiPath(RPA)  最新技術動向  OpenStack  システムトラブルシュート 

第5回 Ruby1.8.7からのバージョンアップ (松永紘) 2013年7月

 5/30(木)から6/1(土)までの3日間、東京国際交流館で開催された「RubyKaigi2013」。2011年に一度終了した「日本Ruby会議」が、より国際的な「Kaigi」としてrebootされました(*1)。実際の様子はUstreamにて視聴可能ですので、ご興味がある方は是非ご覧ください(*2)。

 さて今回はRuby1.8.7からのバージョンアップを取り上げます。前述のRubykaigiでは「Ruby1.8.7」と題された追悼セッションも行われましたが(*3)、2013年6月を持ってRuby1.8.7の全てのサポートが終了します(*4)。セキュリティフィックスも行われないため、1.9もしくは2.0にバージョンアップすることが強く推奨されます。
 弊社でも先日1.8.7のRailsアプリケーションを1.9.3にバージョンアップしましたので、その時の対応内容をご紹介いたします。

エンコーディング関連

 1.9から「文字列オブジェクト(*5)」、「スクリプトそのもの」、「I/O対象のデータ」の3つがエンコーディング情報を持つようになりました。1.8から1.9にバージョンアップする際は、これらのエンコーディング情報を適切に設定する必要があります。
 今回の場合はスクリプトエンコーディングの設定だけ行えばよかったのですが、全てのソースコードにマジックコメント(*6)を設定するのはかなりの手間です。そこでマジックコメントを自動で挿入してくれるGem「magic_encoding」を使用しました。
 本家のものだと拡張子が「.erb」のファイルに対応していないため(*7)、forkされたGemを使用します。

# Rubygems以外からGemをインストールする際に便利なspecific_installをインストール
gem install specific_install

# Github上にあるforkされたmagic_encodingをインストール gem specific_install -l 'git://github.com/airblade/magic_encoding.git'
# マジックコメントの挿入 magic_encoding utf-8 (Railsアプリケーションのパス)

 ちなみに2.0ではスクリプトエンコーディングがデフォルトではUTF-8となるため、UTF-8でコードを書いている場合はマジックコメントが不要になります(*8)。

Date.exist?

 画面から入力された日付の妥当性を確認するため「Date.exist?」を使用していましたが、メソッドそのものが削除されており「NoMethodError」が発生します。1.9.3では代替のメソッドとして「Date.valid_date?」が定義されていますので、そちらを使用しました。
 なお、1.8.7にも「Date.valid_date?」は存在しますが、1.9.3とは挙動が異なるので注意が必要です(*9)。

Object#id

 もともと「Object#id」は1.8.7でもobsoleteで、1.9では削除されています。今回の場合、ActiveRecordオブジェクト(*10)が格納されるべき変数に別のオブジェクトが格納されていたため、「NoMethodError」が発生していました。1.9.3にバージョンアップしたことで、逆に隠れていた不具合を発見できた例ですね。

Object#methods

 対象のオブジェクトがあるメソッドを持っているかどうかチェックするため、以下のようなコードを書いていました。

if obj.methods.include?("one_method")
  obj.one_method
else
  # 持っていない場合の処理
    ・・・
end

 ところが1.9系だと「Object#methods」がSymbolの配列を返すようになったため、以下のように修正する必要があります。

if obj.methods.include?(:one_method)
  # 以下略

 他にも「Module.constants」や「Object#instance_variables」といった名前の一覧を返すメソッドは全てSymbolの配列を返すようになっています。上記のような比較を行っているコードは注意が必要です(*11)。

 以上が弊社アプリケーションの対応内容です。各アプリケーションによって当然対応内容は変わってくると思いますが、一つの例として参考になれば幸いです。
 なお、1.9から2.0にバージョンアップする際はここまで大変になることはなさそうですね(*12)。

 それでは、Enjoy Ruby!

注釈

*1:海外からの参加者が多く、セッションの半分くらいは英語で行われていました。

*2:「http://www.ustream.tv/channel/rubykaigi1」もしくは「http://www.ustream.tv/channel/rubykaigi2」で視聴できます。

*3:実際に黙とうも行われました。

*4http://www.ruby-lang.org/ja/news/2011/10/07/plans-for-1-8-7/

*5:正確には正規表現オブジェクトも含みます。

*6:スクリプトエンコーディングを設定するコメント文で、通常ファイルの一行目に記述します。

*7:「.rb」、「.rake」、「.haml」に対応しているようです。

*8:今回の例とは関係ないですが、プログラミング初心者が触れるという点において、いわゆる「おまじない」が減ったというのはとてもいいことだと思います。

*9:正しい日付の場合、1.8.7では相当するユリウス日(Numeric)を返していましたが、1.9系ではtrueを返すようになっています。

*10:ActiveRecordオブジェクトのidメソッドを使うことで、該当レコードの主キー値を取得しようとしていました。

*11:例外が発生するわけではないので、原因を調べるのにかなり苦労しました。

*12http://www.ruby-lang.org/ja/news/2013/02/24/ruby-2-0-0-p0-is-released/

 


 

 [IT研修]注目キーワード   Python  UiPath(RPA)  最新技術動向  OpenStack  システムトラブルシュート