Bug #515

String#rindexが期待通りに動かない

Added by Takeyuki FUJIOKA about 7 years ago. Updated over 4 years ago.

[ruby-dev:36033]
Status:Closed
Priority:Normal
Assignee:Yui NARUSE
ruby -v: Backport:

Description

=begin
# -- coding: utf-8 --
str="原稿システム原稿原稿"
p str.size
p str.rindex(/<DT/,str.size)

% ruby -Ku /tmp/jikken2.rb
35
30
% ruby19 /tmp/jikken2.rb

14
nil

となり、nilになります。ただ、

# -- coding: utf-8 --
str="原稿"
p str.size
p str.rindex(/<DT/,str.size)

% ruby19 /tmp/jikken2.rb
6
2

これだと動きます。
=end

History

#1 Updated by Usaku NAKAMURA about 7 years ago

=begin
こんにちは、なかむら(う)です。

In message " [Bug #515] String#rindexが期待通りに動かない"
on Aug.28,2008 23:08:08, redmine@ruby-lang.org wrote:

Bug #515: String#rindexが期待通りに動かない
http://redmine.ruby-lang.org/issues/show/515

String#indexおよびString#rindexで第二引数が文字単位での位置で
なくバイト単位の位置になっています。

それは末尾のパッチで直る気がするんですが、元のテストコードは
まだ通らなくて、

in `rindex': incompatible character encodings: UTF-8 and US-ASCII (EncodingCompatibilityError)

になります。
rb_enc_check()が文字列同士じゃないときに中身まで踏み込んだ互
換性確認をしてくれないせいなんですが、どうするのが正しいんで
しょう...

Index: string.c
===================================================================
--- string.c (revision 18896)
+++ string.c (working copy)
@@ -2168,6 +2168,9 @@ rb_str_index_m(int argc, VALUE *argv, VA
}
}

  • pos = str_offset(RSTRING_PTR(str), RSTRING_END(str), pos,
  •       rb_enc_check(str, sub), single_byte_optimizable(str));
    

    +
    switch (TYPE(sub)) {
    case T_REGEXP:
    pos = rb_reg_adjust_startpos(sub, str, pos, 0);
    @@ -2278,6 +2281,9 @@ rb_str_rindex_m(int argc, VALUE *argv, V
    pos = len;
    }

  • pos = str_offset(RSTRING_PTR(str), RSTRING_END(str), pos,

  •       rb_enc_check(str, sub), single_byte_optimizable(str));
    

    +
    switch (TYPE(sub)) {
    case T_REGEXP:
    /* enc = rb_get_check(str, sub); */

    それでは。

    U.Nakamura usa@garbagecollect.jp

=end

#2 Updated by Yui NARUSE about 7 years ago

=begin
成瀬です

U.Nakamura wrote:

String#indexおよびString#rindexで第二引数が文字単位での位置で
なくバイト単位の位置になっています。

それは末尾のパッチで直る気がするんですが、元のテストコードは
まだ通らなくて、

in `rindex': incompatible character encodings: UTF-8 and US-ASCII (EncodingCompatibilityError)

になります。
rb_enc_check()が文字列同士じゃないときに中身まで踏み込んだ互
換性確認をしてくれないせいなんですが、どうするのが正しいんで
しょう...

regexp は中身にまで踏み込む必要はないんじゃないですかね。
regexp の場合、もとから encoding に中身が反映されているので。
そのため、regexp.encoding == US-ASCII の場合の例外処理を入れるだけかと思います。

あとは、file と encoding ですか。

--- encoding.c (revision 18915)
+++ encoding.c (working copy)
@@ -631,6 +631,10 @@ rb_enc_compatible(VALUE str1, VALUE str2
if (!rb_enc_asciicompat(enc1) || !rb_enc_asciicompat(enc2)) {
return 0;
}
+ if (BUILTIN_TYPE(str2) == T_REGEXP && enc2 == rb_usascii_encoding())
+ return enc1;
+ if (BUILTIN_TYPE(str1) == T_REGEXP && enc1 == rb_usascii_encoding())
+ return enc2;

  if (BUILTIN_TYPE(str1) != T_STRING) {
     VALUE tmp = str1;

--
NARUSE, Yui naruse@airemix.jp

=end

#3 Updated by Yui NARUSE about 7 years ago

  • Category set to M17N
  • Assignee set to Yui NARUSE

=begin

=end

#4 Updated by Takeyuki FUJIOKA about 7 years ago

=begin
藤岡です。

usaさんとnaruseさんのパッチを取り込んだら
期待通りの結果になりました。

regexp は中身にまで踏み込む必要はないんじゃないですかね。
regexp の場合、もとから encoding に中身が反映されているので。
そのため、regexp.encoding == US-ASCII の場合の例外処理を入れるだけかと思います。

あとは、file と encoding ですか。

--- encoding.c (revision 18915)
+++ encoding.c (working copy)
@@ -631,6 +631,10 @@ rb_enc_compatible(VALUE str1, VALUE str2
if (!rb_enc_asciicompat(enc1) || !rb_enc_asciicompat(enc2)) {
return 0;
}
+ if (BUILTIN_TYPE(str2) == T_REGEXP && enc2 == rb_usascii_encoding())
+ return enc1;
+ if (BUILTIN_TYPE(str1) == T_REGEXP && enc1 == rb_usascii_encoding())
+ return enc2;

 if (BUILTIN_TYPE(str1) != T_STRING) {
    VALUE tmp = str1;

=end

#5 Updated by Yui NARUSE about 7 years ago

  • Status changed from Open to Closed
  • % Done changed from 0 to 100

=begin
Applied in changeset r18916.
=end

Also available in: Atom PDF