有理数と複素数のsuffixリテラル
コンピュータにおいて小数を表現する手段として最も普及しているのが「浮動小数点」であり、Rubyで「1.2」と評価した時も浮動小数点として表現されています。詳細については割愛します(ここで筆者が説明するよりもわかりやすい解説がたくさんあります。入り口として浮動小数点数#エラー(誤差) - Wikipedia など)が、肝心なのは、この浮動小数点を使って演算を行うと誤差が発生することがある、ということです。
たとえば「1.15を100倍して115にする」という計算にすら罠が潜んでいます。
浮動小数点誤差問題を回避するひとつの手段がRational(有理数)クラスを使うことでした。Rationalには分子と分母を渡して有理数を作成します(有理数とは分数で表せる数のことです)。たとえばRational(1, 3)
を評価すれば「3分の1」になる、という具合です。
Ruby2.1から追加された「有理数のsuffixリテラル」とは、Rational(1, 3)
と書くのは面倒だから「1/3r
」と書けるようにしようぜ、というものです。最後のrがポイントで、要は新機能というわけではなく、可読性を上げる新構文です。なおr
を付けないと普通の整数除算になります。
そして複素数についてもだいたい事情は同じで、いままで複素数を作成するためには実部と虚部をそれぞれ渡してComplex(2, 1)
とする必要があったところを、2 + 1i
と書けるようにしたものです。
こちらは数式そのままの形で書けるので、有理数よりも見た目が素敵な感じになります。
Exception#cause
次にException#cause
です。
Rubyを使って開発していると、例外を補足して、文脈を加味した別の例外を再raiseするようなコードをよく書きます。Ruby2.0までは、例外オブジェクトは最後にraiseされた時の情報しか保持しておらず、そもそもの例外発生箇所を見つけ出すためにはコードをさかのぼって突き止める必要がありました。
自分で開発するなら例外設計を改善すれば良いのかもしれませんが、たまたま利用している誰かの作ったgemに、そのgem独自の例外をraiseして来られるとお手上げです。
そこで、Ruby2.1からは例外オブジェクトがいままでraiseされてきた例外を記憶するようになりました。記憶された先祖の例外はException#cause
メソッドで呼び出すことができます。以下に実例を示します。
Ruby2.0まではrescue内でアクセスできるのはe
変数までで、本当の原因である0除算に関する情報が隠蔽されてしまっています。ここでcause
を使うと、そもそもMyAppException
を引き起こした原因であるZeroDivisionError
に到達することが出来ます。
ちなみにそれ以上遡れない場合Exception#cause
はnilを返します。
参考: 背景や議論は、当機能の提案がなされたIssueページ "Feature #8257: Exception#cause to carry originating exception along with new one" に詳しいです。
最後のページではModule#refine
とusing
による限定的クラス拡張を取り上げます。