Cで拡張ライブラリ

を書こうとしたんだけど,makeでよく解らんエラー出たので後回しにして,RubyでListライブラリを書くことに.carやcdrを使ってScheme的に書けるようにするのが目標.
リスト構造って凄いね.inspectメソッドも再帰で書いちゃった.eachも適当に定義してEnumerableをincludeすると楽しい.でも,これだとmapで配列が返ってくるので,リストが返るように再定義.

irb(main):001:0> require 'list'
=> true
irb(main):002:0> list = List.new(1, 2, 3)
=> (1 2 3)
irb(main):003:0> list.car
=> 1
irb(main):004:0> list.cdr
=> (2 3)
irb(main):005:0> list.map(&:succ)
=> (2 3 4)

楽しいなぁ.でも,ListがmoduleだったりList.newするとPairのインスタンスが返ってきたりして,実体はかなりきもいことになってる気がしないでもない.
話変わるけど,Symbol#to_procがクールすぎる.1.8なので自分で書き足しておいた.


ところで俺のfoldを見てくれ.こいつをどう思う?

def fold(init, *args, &block)
  result = fold(yield(init, *(args.map(&:car))), *(args.map(&:cdr)), &block)
rescue NoMethodError
  init
end

終端チェックが面倒なので例外拾うようにした.酷いコードのような気もするし,気持ち悪い気もするけど,自分ではこれ以上すっきり書ける方法は思い浮かばなかった.
誰かいい書き方があったら教えて下さい.


使う時はこんな感じ.引数の順序はEnumerable#injectに合わせた.

require 'List'
include List
foo, bar = List.new(1, 2, 3), List.new(4, 5, 6)

p fold(0, foo, bar) {|r, x, y|
  r + x * y
}
# => 32