kiyoka.2009_04_22 RSSPLAIN

Related pages: !kiyoka.blog.list !kiyoka.blog.2009_04
5555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555
5

[Nendo] Ruby標準ライブラリを使ってNendoのライブラリ実装をサボりまくりな話

5

私がRubyで書いているLisp方言、 Nendoの開発状況続き。

5

 

5

RubyでLisp処理系を作ると楽できる

5

例えば、sort関数。

5

仕様は『引数にリストを取って、ソート済みの新しいリストを返す』というもの。

5

 

5
 nendoが動いている様子。
5
$ ./nendo 
5
nendo> (sort '(1 5 6 3 4))
5
(1 3 4 5 6 )
5

 

5
 Rubyでは
5
$ irb
5
>> [1, 5, 6, 3, 4].sort
5
=> [1, 3, 4, 5, 6]
5

 

5

さて、nendoの実装はというと

5
  def getIFunc( name )
5
    case name
5
      .
5
      略
5
      .
5
    when 'sort'
5
      lambda {|arg|     arg.to_arr.sort.to_list }
5
      .
5
      略
5
      .
5
    end
5
  end
5

となっている。

5

引数argはconsセル用の 'Cellクラス' の連結リストで、一旦RubyのArrayに変換することでRuby標準のsort関数を使っている。

5

 

5

上の様に短く書けるのはCellクラスにイテレータを実装したことと、Arrayクラスにto_listメソッドを追加したため。

5
 Cellクラスのキモの部分
5
class Cell
5
  include Enumerable
5
5
  def initialize( car = Nil.new, cdr = Nil.new )
5
    @car = car
5
    @cdr = cdr
5
  end
5
  attr_accessor :car, :cdr
5
    .
5
    略
5
    .
5
  def each                    # Supporting iterator
5
    it = self
5
    while Nil != it.class
5
      yield it
5
      it = it.cdr
5
    end
5
  end
5
5
  def to_arr
5
    self.map {|x| x.car}
5
  end
5
end
5

 

5
 こちらは、動的にArrayクラスにto_listを追加するコード
5
class Array
5
  def to_list
5
    cells = self.map { |x|
5
      Cell.new( x )
5
    }
5
    ptr = cells.pop
5
    cells.reverse.each { |x|
5
      x.cdr = ptr
5
      ptr = x
5
    }
5
    return ptr
5
  end
5
end
5

 

5

sortだけでなくreverseとuniqも同じ

5
 一旦Arrayに変換するだけで良い関数はsortと同様に書ける
5
  def getIFunc( name )
5
    case name
5
      .
5
      .
5
    when 'sort'
5
      lambda {|arg|     arg.to_arr.sort.to_list }
5
    when 'reverse'
5
      lambda {|arg|     arg.to_arr.reverse.to_list }
5
    when 'uniq'
5
      lambda {|arg|     arg.to_arr.uniq.to_list }
5
      .
5
      .
5
    end
5
  end
5

 

5

sortに評価関数を指定したい場合は?

5

ウーン… どうしようかな…

5

うまくこの仕組みにのっかって行けるかどうか微妙。

5

その時はsort関数をnendoで実装しなおさないといけないなぁ。

5

reverseはそのままでいいかも。

5

 

5

...comment disabled...

5

 

5

 

5

 

5

 

5