たけ(tk)です。

[ruby-dev:21932] rough / tabs.rb にて 
Minero Aoki <aamine / loveruby.net> さん 曰く:

> 文句を言うだけでは何なので別の実装を書きました。
> 書いたのを末尾に添付しときます。

次のようになってしまったのですが、仕様でしょうか? rough では直っている
のかな?

  str ="\t123\t    567     789"
  p str.unexpand(4)     #=> "\t123\t    567     789"
  p str.unexpand_all(4) #=> "16"

  str ="    123     567     789"
  p str.unexpand(4)     #=> "\t123     567     789"
  p str.unexpand_all(4) #=> "16"

自作のものと比べてみたのですが、自作のほう(detab)がexpand よりも速いみ
たいです。

どういう場合に速くなるのでしょうか?

----
#! ruby -Ks
#-- String_tab.rb
#-- String_tab.pi

class String
  def detab(tab_size=8)
    gsub( /(.*?)\t/ ){ $1 + ' '*( tab_size - ( $1.size % tab_size) ) }
  end
  def entab(tab_size=8)
    ret =  (/\t/ =~ self) ? self.detab(tab_size) : self.dup
    (self.size/tab_size).downto(0){|n|
      pos = n*tab_size
      if ret[pos+tab_size-1] == 32
        ret[pos,tab_size] = ret[pos,tab_size].sub(/ *$/,"\t")
      end
    }
    ret
  end
end

if __FILE__ == $0
  require "tabs"
  require "lap"

  str ="\t123\t\t567     789"
  p str.detab(4)  #=> "    123     567     789"
  p str.expand(4) #=> "    123     567     789"
  lap[0]
  1000.times{ str.detab(4) }  ; p lap[0] #=> 0.121
  1000.times{ str.expand(4) } ; p lap[0] #=> 0.33
  1000.times{ str.detab(4) }  ; p lap[0] #=> 0.2
  1000.times{ str.expand(4) } ; p lap[0] #=> 0.201
  1000.times{ str.detab(4) }  ; p lap[0] #=> 0.16
  1000.times{ str.expand(4) } ; p lap[0] #=> 0.21
  1000.times{ str.detab(4) }  ; p lap[0] #=> 0.18
  1000.times{ str.expand(4) } ; p lap[0] #=> 0.211
  1000.times{ str.detab(4) }  ; p lap[0] #=> 0.17
  1000.times{ str.expand(4) } ; p lap[0] #=> 0.24
  1000.times{ str.detab(4) }  ; p lap[0] #=> 0.14
  1000.times{ str.expand(4) } ; p lap[0] #=> 0.231

  str ="\t123\t    567     789"
  p str.entab(4)        #=> "\t123\t\t567\t\t789"
  p str.unexpand(4)     #=> "\t123\t    567     789"
  p str.unexpand_all(4) #=> "16"

  str ="    123     567     789"
  p str.entab(4)        #=> "\t123\t\t567\t\t789"
  p str.unexpand(4)     #=> "\t123     567     789"
  p str.unexpand_all(4) #=> "16"

  lap[0]
  1000.times{ str.entab(4) }    ; p lap[0]     #=> 0.261
  1000.times{ str.unexpand(4) } ; p lap[0]     #=> 0.14
  1000.times{ str.unexpand_all(4) } ; p lap[0] #=> 0.34

end
----

take_tk = kumagai hidetake