なかだです。

At Tue, 4 Dec 2007 20:17:55 +0900,
Nobuyoshi Nakada wrote in [ruby-dev:32453]:
> At Tue, 4 Dec 2007 17:52:27 +0900,
> Tanaka Akira wrote in [ruby-dev:32452]:
> > "あいうえお".force_encoding("euc-jp").split(//) と (EUC-JP
> > で) 行うと negative string size となります。
> > 
> > % ./ruby -ve 'p "あいうえお".force_encoding("euc-jp").split(//)'
> > ruby 1.9.0 (2007-12-04 patchlevel 0) [i686-linux]
> > -e:1:in `split': negative string size (or size too big) (ArgumentError)
> >         from -e:1:in `<main>'

これ以外にも、
p "あいうえお".partition("う")	#=> ["あい", "う", "お"]

# -*- encoding: shift_jis -*-
p "表示".partition("\\")	#=> ["表", "\\", ""]

とかいろいろおかしなことになってるので、byte/char offsetの使いわ
けに関してはもっと見直す必要がありそうです。

> rb_reg_search()が文字単位の位置を返すのに、rb_str_split_m()では
> byte位置として使っているためですね。BEG()やEND()もbyte位置のまま
> なので、メソッドの戻り値として返すときに文字位置に変換するように
> したほうがいいのではないでしょうか。

とりあえずこっちだけ。


Index: re.c =================================================================== --- re.c (resuult 14122) +++ re.c (working copy) @@ -865,5 +865,5 @@ rb_reg_search(VALUE re, VALUE str, int p OBJ_INFECT(match, str); - return rb_str_sublen(RMATCH(match)->str, result); + return result; } @@ -1836,10 +1836,10 @@ reg_operand(VALUE s, int check) } -static VALUE +static long rb_reg_match_pos(VALUE re, VALUE str, long pos) { if (NIL_P(str)) { rb_backref_set(Qnil); - return Qnil; + return -1; } str = reg_operand(str, Qtrue); @@ -1848,5 +1848,5 @@ rb_reg_match_pos(VALUE re, VALUE str, lo pos += RSTRING_LEN(str); if (pos < 0) { - return Qnil; + return pos; } } @@ -1854,8 +1854,5 @@ rb_reg_match_pos(VALUE re, VALUE str, lo } pos = rb_reg_search(re, str, pos, 0); - if (pos < 0) { - return Qnil; - } - return LONG2FIX(pos); + return pos; } @@ -1872,5 +1869,7 @@ VALUE rb_reg_match(VALUE re, VALUE str) { - return rb_reg_match_pos(re, str, 0); + long pos = rb_reg_match_pos(re, str, 0); + if (pos < 0) return Qnil; + return LONG2FIX(pos); } @@ -1937,4 +1936,5 @@ rb_reg_match2(VALUE re) return Qnil; } + start = rb_str_sublen(line, start); return LONG2FIX(start); } @@ -1982,6 +1982,6 @@ rb_reg_match_m(int argc, VALUE *argv, VA } - result = rb_reg_match_pos(re, str, pos); - if (NIL_P(result)) { + pos = rb_reg_match_pos(re, str, pos); + if (pos < 0) { rb_backref_set(Qnil); return Qnil;
-- --- 僕の前にBugはない。 --- 僕の後ろにBugはできる。 中田 伸悦