Ruby Freaks Lounge

第3回 Ruby1.9の新機能ひとめぐり(中編):洗練された文法と意味論

この記事を読むのに必要な時間:およそ 2.5 分

実引数に関する改善

複数の実引数展開のサポート(multi split)

配列の各要素を引数としてメソッドを呼び出す記法は1.8にもありました。しかし,メソッド呼び出しあたり1つしか書けないという制約がありました。1.9ではこの制約が取り除かれました。

コード4 複数の実引数展開が可能に

def foo(a, b, c, d)
  p [a, b, c, d]
end

ary = [1, 2]

foo(*ary, *ary)  #=> [1, 2, 1, 2]

この機能は配列リテラルの中でも使えます。テーブルの作成などに便利でしょう。

コード5 複数の実引数展開を持つ配列リテラル

p [*"0".."2", *"7".."9"]  #=> ["0", "1", "2", "7", "8", "9"]

後置必須引数のサポート(post arg)

メソッド定義の仮引数では,オプショナル引数やrest引数(*つきの引数)の後に必須引数を書けるようになりました。

コード6 後置必須引数の例

def foo(a, b, *ary, z)
  p [a, b, ary, z]
end

foo(1, 2, 3, 4, 5) #=> [1, 2, [3, 4], 5]

この機能は,[]=という名前のメソッドが任意個の引数を受け取るときに書きやすくなります。

コード7 []=で代入される値を後置必須引数として受け取る

# []=という名前のメソッドで使用すると便利
class Foo
  def []=(*ary, val)
    p "[#{ ary.join(",") }] <- #{ val }"
  end
end
x = Foo.new
x[1] = 9       #=> "[1] <- 9"
x[1, 2] = 9    #=> "[1, 2] <- 9"
x[1, 2, 3] = 9 #=> "[1, 2, 3] <- 9"

また,多値代入でも使用できます。

コード8 後置必須引数で配列の最後の値を取り出す

first, *, last = [1, 2, 3, 4]
p first   #=> 1
p last    #=> 4

その他細かい話

キーワード引数風表記

キーワード引数とは,引数をキーワードつきで与えることで,引数の順序を自由に変えられる仕組みです。Rubyはキーワード引数を直接サポートしませんが,メソッド呼び出しの最後の引数でキーワード引数のような記述をできるようになりました。

コード9 キーワード引数風のメソッド呼び出し

def set_pixel(h)
  # キーワード引数はシンボルがキーのハッシュとして受け取る
  @field[h[:y]][h[:x]] = h[:color]
end

# 呼び出しはキーワード引数風に
set_pixel(x:30, y:50, color:"red")
set_pixel(color:"black", x:40, y:50)

従来でもブレースのみの省略はできましたが,よりキーワード引数風の表記が可能になりました。

例えば,ファイル I/OのAPIではエンコーディングをハッシュで指定できることが多いため,以下のように書くことができます。

コード10 ファイルのエンコーディングをキーワード引数風に指定する例

File.read("sample.txt", encoding: "UTF-8")

また,この記法はハッシュリテラルの中でも使えます。

コード11 キーワード引数風の表記を用いたハッシュリテラル

p({dog: "bow-wow", cat: "mew"})  #=> {:dog => "bow-wow", :cat => "mew"}

改行可能な箇所の追加

Rubyは改行によって文を区切るため,文や式の途中で下手に改行を行うと文法エラーになります。ただし,明らかに途中であることがわかる場合には改行を入れることができます(括弧でくくられた文の中や,コンマや演算子の直後など⁠⁠。Ruby1.9でもこの方針は同じですが,改行できる箇所が2点増えました。

コード12 追加された改行可能箇所

# 条件演算子(いわゆる三項演算子)の:の直前
x = cond ? foo
         : bar

# メソッド呼び出しのピリオドの直前
 foo
.bar
.baz

ラムダ式の別記法

Rubyにはラムダ式を定義する関数lambdaがありますが,これの別記法として,定義する記法->と呼び出しを行う記法.()が追加されました。

コード13 Proc(ラムダ式)の別記法

# 1を足すクロージャを定義する(lambda {|x| x + 1 }とほぼ同義)
# '->'と'('の間にスペースを入れられないことに注意,括弧は省略可能
add_1 = ->(x) { x + 1 }

# add_1を呼び出す(add_1.call(42)の省略)
p add_1.(42) #=> 43

使うかどうかは個人の好み次第ですが,しばしば話題になるので取り上げました(->はλを右に45度傾けた形らしいです⁠⁠。

また,procがProc.newと同じ意味になったという改善もあります(Proc内でreturnした場合の挙動⁠⁠。

まとめ

以上のようにRuby1.9における文法や意味論の変更は,ルールのシンプル化が中心です。

次回の後編では,落穂ひろいとして,1.9の知っておくとお得な機能を紹介したいと思います。

著者プロフィール

遠藤侑介(えんどうゆうすけ)

某電機メーカーで研究職勤務。個人活動として,2008年1月よりRubyの開発に参加。テストを書いたり,バグをとったり,バグを入れたりしています。好きな言語はRubyとHaskellとOCaml 。使う言語はRubyとC 。

URLhttp://d.hatena.ne.jp/ku-ma-me/