From: Minero Aoki Date: 2003-12-18T18:52:49+09:00 Subject: [ruby-dev:22301] Re: rough / tabs.rb ----Next_Part(Thu_Dec_18_18:52:46_2003_809)-- Content-Type: Text/Plain; charset=iso-2022-jp Content-Transfer-Encoding: 7bit 青木です。 In mail "[ruby-dev:22271] Re: rough / tabs.rb" take_tk wrote: > たけ(tk)です。 > 次のようになってしまったのですが、仕様でしょうか? rough では > 直っているのかな? しまった。メールを出すときに何気なく書き換えたところが 間違ってました。申し訳ない。 あと typo らしきところもあったのでそれも直しときました。 > 自作のものと比べてみたのですが、自作のほう(detab)がexpand よりも速いみ > たいです。 > > どういう場合に速くなるのでしょうか? ぼくの書いたやつは行の先頭にタブが集中してるケースに最適化しま した。条件を同じにして (detab をモジュールに定義して) 計測すると、 \t が 2 個までは detab の勝ち、3 個だと expand の勝ちって感じです。 ま、でもたけさんの detab のほうが定義がすっきりしているので、 そっちのほうがいいかも。ちょっとだけ変えてとりこんでみました。 ついでにテストも付けておきます。 ------------------------------------------------------------------- 青木峰郎 ----Next_Part(Thu_Dec_18_18:52:46_2003_809)-- Content-Type: Text/Plain; charset=us-ascii Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="tabs.rb" # # Copyright (c) 2001 Akinori MUSHA # # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # 1. Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # 2. Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS # OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF # SUCH DAMAGE. # # $Idaemons: /home/cvs/rb/tabs.rb,v 1.2 2001/05/30 09:37:45 knu Exp $ # $Id: tabs.rb,v 1.1 2001/06/01 18:58:29 knu Exp $ module Tabs DEFAULT_TABSTOP = 8 def expand(text, tabstop = DEFAULT_TABSTOP) text.gsub(/(.*?)\t/n) { $1 + ' ' * (tabstop - ($1.size % tabstop)) } end def unexpand(text, tabstop = DEFAULT_TABSTOP) text.gsub(/^[ \t]+/) {|sp| t, s = expand(sp, tabstop).length.divmod(tabstop) "\t" * t + ' ' * s } end def unexpand_all(text, tabstop = DEFAULT_TABSTOP) expand(text, tabstop).map {|line| (line.length - (line.length % tabstop) - tabstop).step(0, -tabstop) {|i| line[i, tabstop] = line[i, tabstop].sub(/ +\z/, "\t") } line }.join('') end module_function :expand, :unexpand, :unexpand_all end class String def expand_tabs(tabstop = Tabs::DEFAULT_TABSTOP) Tabs.expand(self, tabstop) end def expand_tabs!(tabstop = Tabs::DEFAULT_TABSTOP) replace(Tabs.expand(self, tabstop)) end def unexpand_tabs(tabstop = Tabs::DEFAULT_TABSTOP) Tabs.unexpand(self, tabstop) end def unexpand_tabs!(tabstop = Tabs::DEFAULT_TABSTOP) replace(Tabs.unexpand(self, tabstop)) end def unexpand_tabs_all(tabstop = Tabs::DEFAULT_TABSTOP) Tabs.unexpand_all(self, tabstop) end def unexpand_tabs_all!(tabstop = Tabs::DEFAULT_TABSTOP) replace(Tabs.unexpand_all(self, tabstop)) end end ----Next_Part(Thu_Dec_18_18:52:46_2003_809)-- Content-Type: Text/Plain; charset=us-ascii Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="test_tabs.rb" require 'tabs' require 'test/unit' class TestTabs < Test::Unit::TestCase include Tabs def test_expand assert_equal '', expand('') assert_equal ' ', expand("\t", 1) assert_equal ' ', expand("\t", 2) assert_equal ' ', expand("\t", 3) assert_equal ' ', expand("\t", 4) assert_equal ' ', expand("\t", 5) assert_equal ' ', expand("\t", 6) assert_equal ' ', expand("\t", 7) assert_equal ' ', expand("\t", 8) #assert_raises(ArgumentError) { # expand(' ', 0) #} assert_equal ' '*9, expand("\t ", 8) assert_equal ' '*10, expand("\t ", 8) assert_equal ' '*11, expand("\t ", 8) assert_equal ' '*12, expand("\t ", 8) assert_equal ' '*13, expand("\t ", 8) assert_equal ' '*14, expand("\t ", 8) assert_equal ' '*15, expand("\t ", 8) assert_equal ' '*16, expand("\t ", 8) assert_equal 'aa ', expand("aa\t", 4) assert_equal 'aa ', expand("aa\t", 5) assert_equal 'aa ', expand("aa\t", 6) assert_equal 'aa ', expand("aa\t", 7) assert_equal 'aa ', expand("aa\t", 8) assert_equal ' ', expand("\t\t", 1) assert_equal ' ', expand("\t\t\t", 1) assert_equal ' ', expand("\t\t\t\t", 1) assert_equal "\n", expand("\n") assert_equal "\n\n", expand("\n\n") assert_equal " \n", expand("\t\n", 2) assert_equal " \n", expand("\t \n", 2) assert_equal 'a', expand("a", 2) assert_equal 'a a', expand("a\ta", 2) assert_equal 'a a a', expand("a\ta\ta", 2) assert_equal 'a a a a', expand("a\ta\ta\ta", 2) assert_equal 'a a a a a', expand("a\ta\ta\ta\ta", 2) end def test_unexpand assert_equal '', unexpand('', 0) assert_equal '', unexpand('', 1) assert_equal '', unexpand('', 2) assert_equal '', unexpand('', 3) assert_equal '', unexpand('', 4) assert_equal '', unexpand('', 5) assert_equal '', unexpand('', 6) assert_equal '', unexpand('', 7) assert_equal '', unexpand('', 8) assert_equal ' ', unexpand(' ', 8) assert_equal ' ', unexpand(' ', 8) assert_equal ' ', unexpand(' ', 8) assert_equal ' ', unexpand(' ', 8) assert_equal ' ', unexpand(' ', 8) assert_equal ' ', unexpand(' ', 8) assert_equal ' ', unexpand(' ', 8) assert_equal "\t", unexpand(' ', 1) assert_equal "\t", unexpand(' ', 2) assert_equal "\t", unexpand(' ', 3) assert_equal "\t", unexpand(' ', 4) assert_equal "\t", unexpand(' ', 5) assert_equal "\t", unexpand(' ', 6) assert_equal "\t", unexpand(' ', 7) assert_equal "\t", unexpand(' ', 8) assert_equal "\t", unexpand("\t") assert_equal "\t\t", unexpand("\t\t") assert_equal "\t\t\t", unexpand("\t\t\t") assert_equal "\t\t ", unexpand("\t\t ") assert_equal "\t\t\t", unexpand("\t\t ", 2) assert_equal "\t\t\t", unexpand("\t \t", 2) assert_equal "\t\t\t", unexpand(" \t\t", 2) assert_equal "\t", unexpand(" \t", 4) end def test_unexpand_all assert_equal "", unexpand_all("") assert_equal "", unexpand_all("", 1) assert_equal "", unexpand_all("", 2) assert_equal "", unexpand_all("", 3) assert_equal "", unexpand_all("", 4) assert_equal "", unexpand_all("", 5) assert_equal "", unexpand_all("", 6) assert_equal "", unexpand_all("", 7) assert_equal "", unexpand_all("", 8) assert_equal "\t", unexpand_all(" ") assert_equal "\t", unexpand_all(" ", 1) assert_equal "\t", unexpand_all(" ", 2) assert_equal "\t", unexpand_all(" ", 3) assert_equal "\t", unexpand_all(" ", 4) assert_equal "\t", unexpand_all(" ", 5) assert_equal "\t", unexpand_all(" ", 6) assert_equal "\t", unexpand_all(" ", 7) assert_equal "\t", unexpand_all(" ", 8) assert_equal "\t", unexpand_all("\t") assert_equal "\t\t", unexpand_all("\t\t") assert_equal "\t\t\t", unexpand_all("\t\t\t") assert_equal "\t\t ", unexpand_all("\t\t ") assert_equal "\t\t\t", unexpand_all("\t\t ", 2) assert_equal "\t\t\t", unexpand_all("\t \t", 2) assert_equal "\t\t\t", unexpand_all(" \t\t", 2) assert_equal "\t", unexpand_all(" \t", 4) assert_equal "a\t", unexpand_all("a ", 4) assert_equal "ab\t", unexpand_all("ab ", 4) assert_equal "abc\t", unexpand_all("abc ", 4) assert_equal "abcd", unexpand_all("abcd", 4) assert_equal "a\ta\ta", unexpand_all("a a a", 4) assert_equal "ab\tab\tab", unexpand_all("ab ab ab", 4) assert_equal "abc\tabc\tabc", unexpand_all("abc abc abc", 4) assert_equal "a\t a", unexpand_all("a a", 4) assert_equal "a\t a", unexpand_all("a a", 4) assert_equal "a\t a", unexpand_all("a a", 4) assert_equal "a\t\ta", unexpand_all("a a", 4) assert_equal "a\t\t a", unexpand_all("a a", 4) assert_equal "\t123\t\t567\t\t789", unexpand_all("\t123\t 567 789", 4) assert_equal "\t123\t\t567\t\t789", unexpand_all(" 123 567 789", 4) end end ----Next_Part(Thu_Dec_18_18:52:46_2003_809)----