2014年12月25日、毎年クリスマス恒例のRuby新バージョンリリースが行われました。既に2ヶ月経過してしまっていますが、新機能・変更点などをざっと紹介したいと思います。
ruby/NEWS at v2.2.0 - ruby/ruby
インクリメンタルGC
Introduce incremental marking for major GC.
Rubyist Magazine - YARV Maniacs 【第 12 回】 インクリメンタル GC の導入
RubyのGCには不断の努力が感じられる歴史があります。かつては最も基本的な(かつ遅いと知られている) Mark & Sweep 方式で、これは不要になったオブジェクトを総ナメしてメモリを解放するというシンプルなものでした。
そこに1.9.3でlazy sweep機能、 2.0.0でBitmap Marking機能、2.1からは世代別GCの"RGenGC"を取り入れて改善を行ってきました。
今回の2.2で取り入れられたインクリメンタルGCは、上記Rubyist Magazineのフレーズを借りると「マークやスイープの処理を細切れにして、GC をちょっとずつ進めていくための仕組み」であると言えます。
※GCそのものについて本記事で詳しい解説は行いませんが、あまり馴染みのない方は 第5章 ガ-ベージコレクション - 『Rubyソースコード完全解説』サポートページ などを参考にすると良いかもしれません。
デフォルト値付きメソッド引数の挙動変更
デフォルト値付き引数での未定義変数参照の挙動が変わりました。そもそも、Rubyは変数への代入式が出現した時点で「変数が未定義ならまずnilで初期化する」という動作をします。そのため未定義変数が自分自身を代入するようなコードを書くと、次のような結果が得られます。
ところが2.1までは「メソッド引数部分」においては地の文とは挙動が異なり、デフォルト引数に変数を代入するコードを書くと、nilで初期化されず「メソッド定義時の環境を参照」していました。これを他の挙動と揃えて「nilの代入」としたのが、ここで言及している2.2での変更点です。
NEWSにて
fixed a very longstanding bug that an optional argument was not accessible in its default value expression.
と書かれている通り、これはバグの扱いになっているようです。
2.1以前のようにメソッド引数定義部分で他のメソッドを参照したい場合は、()
を付けてメソッド呼び出しであることを明確にすればOKです。
次のページでは言語仕様上の他の変更、Binding等のクラスに施された機能追加・修正などを見ていきます。