[#954] Rational — keiju@... (Keiju ISHITSUKA)

けいじゅ@SHLジャパンです.

23 messages 1996/10/30
[#955] Re: Rational — matz@... (Yukihiro Matsumoto) 1996/10/30

まつもと ゆきひろです.

[#968] Re: Rational 1996/10/31

けいじゅ@SHLジャパンです.

[ruby-list:917] Re: [REQ]Get Strings!<3> GETS, SUB

From: sinara@...
Date: 1996-10-28 12:26:01 UTC
List: ruby-list #917
原です。

> まつもと ゆきひろです.

|(7)String#gets がほしい。

ストリームにもストリングにも同じメソッドが使えれば、同じデー
タの形式に同じプログラムで対処できていいかなと。データ形式が
そのままプログラムに反映されるみたいで気持ちいいし。

> これはStringをwrapするクラスで対応すべきだと思っています.簡
> 単ですから書いてみてはいかが?

まあ、こんなのを組み込みで要求するのはどうかとも思ったんですが。^^;
リクエストする前に一応書いてみたんですけど,,,

-----^
class SeekableString
  def initialize(s = "")
    @str = s
    @idx = 0
  end
  def to_s
    @str
  end
  def tell; @idx; end
  def seek(p = 0); @idx = p; end
  def gets(t = $/)
    i = @idx
    if i >= @str.length
      nil
    elsif defined?(t) and (j = @str.index(t, i))
      @idx = j + t.length
      @str[i..@idx-1]
    else
      @idx = @str.length
      @str[i..@idx-1]
    end
  end
  def match(reg)
    if @str[@idx..-1] =~ reg
      [@idx + @str[@idx..-1].index($&), $&.length]
    else
      nil
    end
  end
  def sub!(reg, exp)
    str1, idx1 = @str[@idx..-1], @idx
    if str1.sub!(reg, exp)
      @idx += @str[idx1..-1].index($&) + $&.length
      @str = (if idx1 > 0 then @str[0..idx1-1] else '' end) + str1
    else nil end
  end
  public :gets, :sub!
end
-----$

gets, sub! を再定義すると private method だからだめだといわれて
しまったので、やみくもに public を置いてみたのですけど、使い方は
こんなんでいいでしょうか?


> |(8)イッキ sub, gsub がほしい。
> 
> むむむ,これは現在のregexp matcherでは対応できません.このま
> まの対応は当面は無理ですね.長期的な課題と思ってください.い
> つかregexp matcherを書き換えることがあればその時に採用を検討
> しましょう.いつかperl5の拡張正規表現に対応するために書き換
> えないといけないと思ってはいるのですが….


そうでなんですか。ユーザーで定義しようとするとかなり複雑かつ
不効率になるので、別に sub の拡張というわけでなくても、組み込
みになればと思ったのですが。またの機会に御一考願います。

一応、SeekableString クラスを使って書いてみました。

-----^
def trans!(str, regs, exps) # = ikki sub!
  hits = [];  pos = []
  for i in 0..regs.length-1
    if pos[i] = str.match(regs[i])
      hits.push(i)
    end
  end
  return nil if hits == []
  best = hits.min { |a, b|
      if  (x = (pos[a][0] <=> pos[b][0])) != 0
	x
      else
	pos[b][1] <=> pos[a][1]
      end
    }
  str.sub!(regs[best], exps[best])
end

def gtrans!(str, regs, exps) # = ikki.gsub!
  hit1 = nil
  while(hit =trans!(str, regs, exps))
    hit1 = hit
  end
  hit1
end
-----$
---===-=-=-=-=-=-=-=-=======--=-=-=-==-=-===-=-=-=-=-=-=--=-==-=--
                           Shin-ichro Hara(Nagaoka Univ.of Tech.)

In This Thread