Programming log - Shindo200

イベント参加記録とプログラミング系の雑記

Ruby 2.0.0 の新機能を試す

2013年2月24日に ruby 2.0.0-p0 がリリースされました。早速、rbenv で ruby 2.0.0-p0 をインストールしてみます。インストールのコマンドに付けないといけないオプションは環境によって変わってくるようで、私の環境では下記のコマンドでインストールできました。

※ 環境 (Mac OSX Lion) homebrew で ruby-build と openssl と readline をインストール済み.

$ CC=/usr/bin/gcc-4.2 RUBY_CONFIGURE_OPTS="--with-openssl-dir=`brew --prefix openssl` --with-readline-dir=`brew --prefix readline`" rbenv install 2.0.0-p0

ruby 2.0.0 に切り替えます。

$ rbenv global 2.0.0-p0
$ ruby -v
ruby 2.0.0p0 (2013-02-24 revision 39474) [x86_64-darwin11.4.2]

新機能、変更点

キーワード引数

Ruby 1.9.3 まではハッシュを利用して、キーワード引数を表現していました。

def truncate(text, opts = {})
  opts[:omission] ||= "..."
  opts[:limit] ||= 30
  if text.size > opts[:limit]
    max_size = opts[:limit] - opts[:omission].size
    text = text[0..max_size] + opts[:omission]
  end
  text
end

puts truncate("A ruby is a pink to blood-red colored gemstone.", limit: 20)
# => "A ruby is a pink t..."

Ruby 2.0.0からはメソッド定義の引数部分に [変数名]: [初期値] と書くことで、キーワード引数を利用できるようになりました。

def truncate(text, omission: "...", limit: 30)
  if text.size > limit
    max_size = limit - omission.size
    text = text[0..max_size] + omission
  end
  text
end

puts truncate("A ruby is a pink to blood-red colored gemstone.", limit: 20)
# => "A ruby is a pink t..."

Module#prepend

Module#prepend は Module#include のように指定したモジュールを読み込むメソッドですが、メソッド探索順が include とは違うらしいです。試してみます。

module PrependParent
  def foo
    "PrependParent " + super
  end
end

module IncludeChild
  def foo
    "IncludeChild " + super
  end
end

module PrependChild
  def foo
    "PrependChild " + super
  end
end

class Parent
  prepend PrependParent
  def foo
    "Parent"
  end
end

class Child < Parent
  include IncludeChild
  prepend PrependChild
  def foo
    "Child " + super
  end
end

puts Child.new.foo
# => PrependChild Child IncludeChild PrependParent Parent

クラスで定義されているメソッドより、prepend で読み込んだモジュール内で定義されたメソッドが先に実行されています。メソッド探索順を図で書くと、こんな感じでしょうか。
f:id:Shindo_Masaya:20130228152953j:plain:h400

__dir__

実行中のファイルのあるディレクトリ名を指す疑似変数 __dir__ が追加されました。__DIR__ ではなく __dir__ です。実行中のファイル名を指す擬似変数 __FILE__ はカレントディレクトリからの相対パスを返しますが、__dir__ は絶対パスを返します。ライブラリをロードするときの検索パスに、実行中のファイルがあるディレクトリを含めたい場合、File.dirname(__FILE__) で実行中のファイルがあるディレクトリを取得して、$LOAD_PATH に追加していましたが、Ruby 2.0.0 からは __dir__ でディレクトリを取得して、$LOAD_PATH に追加すれば良さそうです。

# Ruby 1.9.3 まで
$LOAD_PATH << File.dirname(__FILE__)
# Ruby 2.0.0 からは、これでも良い
$LOAD_PATH << __dir__

シンボルの配列を簡単に作るリテラル %i

%w と同じような書き方でシンボルの配列を作れるようになりました。

%i[foo bar]
# =>[:foo, :bar]

default UTF-8 encoding

デフォルトのファイル文字コードが ASCII から utf-8 に変更されましたので、マジックコメント「# coding: utf-8」はいらなくなりました。

Array#bsearch

ソートされた配列に対して、ブロックで指定した条件に当てはまる最初の要素をバイナリサーチで探すメソッドが追加されました。

ary = [1, 3, 7, 9, 15]
puts ary.bsearch {|x| x > 8}
# => 9

るびまで知ったのですが、こんな面白いメソッドが追加されていたのですね。
るびまの記事: http://jp.rubyist.net/magazine/?0041-200Special-note#l14

まだまだ他にもあるのですが、とりあえずここまでにします。