injectをwhileの代わりに使う

Railsのacts_as_treeで、あるノードの親を全て取得するのに

def parents
  ret = []
  current = self
  while current.parent
    ret << current.parent
    cur = current.parent
  end
  ret
end

とかやってたんですけど、どうもどんくさくて嫌なので無理やり回避。

class LazyArray                                                
  def initialize(first, &next_block)                           
    @current = first                                           
    @next_block = next_block                                   
  end                                                          
                                                               
  def inject(sum, &block)                                      
    block.call sum, @current                                   
    inject sum, &block if @current = @next_block.call(@current)
    sum                                                        
  end                                                          
end                                                            

って言うのを作って、修正後はこう。

def parents
  LazyArray.new(parent){|d| d.parent}.inject([]){|s, d| s << d}
end

LazyArrayという名前が誇大に過ぎると言う文句は、まぁその通りだと思います。