第1回では、YARVやFiberなど有名な機能と、配列処理の強化について紹介しました。
今回は、Ruby1.9で導入された新しい文法や意味論を中心に紹介します。
ブロックパラメータ(仮引数)に関する変更
ブロックパラメータのスコープがブロックローカルに
ブロック中の変数はスコープがやや曖昧でした。初出の変数の場合はブロックローカル(ブロックの終了と共に変数も消える)で、ブロックの外ですでに宣言されていた変数の場合はその変数を指す、というルールで、ブロックの外まで見ないと変数のスコープが判断できませんでした。
この問題を軽減するため、1.9ではブロックパラメータは常にブロックローカルであると改定されました。
これによって、ary.map{|x| ... } のような簡単なブロックを定義する際に、いちいちブロックパラメータ名の衝突を気にする必要がなくなりました。
ただしこの変更には互換性の問題があります。つまり、変数名を意図的に衝突させていたようなコードが動かなくなります。心配な人は、rubyに-wオプションを与えて実行することでwarningを出してくれますので、チェックするといいでしょう。
また、ブロックパラメータの後にセミコロンと変数名の列を書くことで、ブロックパラメータ以外にブロックローカルな変数を宣言する機能もあります。
ブロックとメソッドの仮引数のルールが統一
ブロックの仮引数にオプショナル引数やrest引数(*つきの引数)などが書けるようになりました。これによってブロックとメソッドの仮引数が同じルールになり、シンプルになりました。
この機能はAPI設計の幅を広げると思います。また、Module#define_methodによってオプショナル引数やブロックを受け取るメソッドが定義できるようになりました。
ただし、|@foo|のように、ブロックパラメータにインスタンス変数やクラス変数、アクセサメソッドなどを書くことはできなくなったことには注意が必要かもしれません。
実引数に関する改善
複数の実引数展開のサポート(multi split)
配列の各要素を引数としてメソッドを呼び出す記法は1.8にもありました。しかし、メソッド呼び出しあたり1つしか書けないという制約がありました。1.9ではこの制約が取り除かれました。
この機能は配列リテラルの中でも使えます。テーブルの作成などに便利でしょう。
後置必須引数のサポート(post arg)
メソッド定義の仮引数では、オプショナル引数やrest引数(*つきの引数)の後に必須引数を書けるようになりました。
この機能は、[]=という名前のメソッドが任意個の引数を受け取るときに書きやすくなります。
また、多値代入でも使用できます。
その他細かい話
キーワード引数風表記
キーワード引数とは、引数をキーワードつきで与えることで、引数の順序を自由に変えられる仕組みです。Rubyはキーワード引数を直接サポートしませんが、メソッド呼び出しの最後の引数でキーワード引数のような記述をできるようになりました。
従来でもブレースのみの省略はできましたが、よりキーワード引数風の表記が可能になりました。
例えば、ファイル I/OのAPIではエンコーディングをハッシュで指定できることが多いため、以下のように書くことができます。
また、この記法はハッシュリテラルの中でも使えます。
改行可能な箇所の追加
Rubyは改行によって文を区切るため、文や式の途中で下手に改行を行うと文法エラーになります。ただし、明らかに途中であることがわかる場合には改行を入れることができます(括弧でくくられた文の中や、コンマや演算子の直後など)。Ruby1.9でもこの方針は同じですが、改行できる箇所が2点増えました。
ラムダ式の別記法
Rubyにはラムダ式を定義する関数lambdaがありますが、これの別記法として、定義する記法->と呼び出しを行う記法.()が追加されました。
使うかどうかは個人の好み次第ですが、しばしば話題になるので取り上げました(->はλを右に45度傾けた形らしいです)。
また、procがProc.newと同じ意味になったという改善もあります(Proc内でreturnした場合の挙動)。
まとめ
以上のようにRuby1.9における文法や意味論の変更は、ルールのシンプル化が中心です。
次回の後編では、落穂ひろいとして、1.9の知っておくとお得な機能を紹介したいと思います。