歴史的に見るとyieldを使うのが先にあって、&block (ブロック引数)でオブジェクトとして受けとり、callメソッドで呼び出すのが後から登場している。 記法的に考えると後者の方が優れている(現在の実装では、効率は前者の方が少しだけ良い)。
しかし、ブロック引数を使うとエラーの出力が良くないのが欠点である。 つまり、
def foo1 yield end def foo2(&block) block.call end foo1 # => in `foo1': no block given (LocalJumpError) foo2 # => in `foo2': undefined method `call' for nil:NilClass (NoMethodError)
どちらもエラーには違いないが、メッセージが直接的に意味するところを考えると 前者の方が優れている。
で、1.9ではこうしようかなと考えている
すると、こうなる。
def foo1 yield end def foo2(&block) block.yield end foo1 # => in `foo1': no block given (LocalJumpError) foo2 # => in `nil.yield': no block given (LocalJumpError)
「foo2」が表示されないのが惜しいが、まあ、だいぶマシになったのではないだろうか。
ガーベージコレクションの大統一理論。 だいぶ古い論文(2004)だが、最近改めて読み直したので。
一方にルートから生きているオブジェクトをトレースするtracing gcがあり、 他方に参照数を数えることにより、死んだオブジェクトを発見するrefernce counting gcがある。この二者は「物質」と「反物質」のように相対する関係であり、 片方を改善するテクニックには、かならずそれに対応する他方を改善するテクニックが存在する。結局は組み合わせにすぎない、という理論。
将来、誰も知らなかったようなGC手法が登場する可能性は低いことを示しているが、 逆に状況に最適なテクニックのセットを発見するための、理論的な背景にもなるので 非常に有用のような気がする。