«前の日記(2006年05月28日) 最新 次の日記(2006年05月30日)» 編集

Matzにっき


2006年05月29日 [長年日記]

_ [Ruby] yieldとProc#call

歴史的に見ると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ではこうしようかなと考えている

  • Proc#yieldメソッドを導入(これには他にも理由があるのだが、別のときに述べる)
  • nil.yieldメソッドも用意。これが「no block given」のメッセージを出す

すると、こうなる。

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」が表示されないのが惜しいが、まあ、だいぶマシになったのではないだろうか。

_ A Unified Theory of Garbage Collection

ガーベージコレクションの大統一理論。 だいぶ古い論文(2004)だが、最近改めて読み直したので。

一方にルートから生きているオブジェクトをトレースするtracing gcがあり、 他方に参照数を数えることにより、死んだオブジェクトを発見するrefernce counting gcがある。この二者は「物質」と「反物質」のように相対する関係であり、 片方を改善するテクニックには、かならずそれに対応する他方を改善するテクニックが存在する。結局は組み合わせにすぎない、という理論。

将来、誰も知らなかったようなGC手法が登場する可能性は低いことを示しているが、 逆に状況に最適なテクニックのセットを発見するための、理論的な背景にもなるので 非常に有用のような気がする。


«前の日記(2006年05月28日) 最新 次の日記(2006年05月30日)» 編集