Backport #809
closedString#ord and String#[gs]etbyte for 1.8
Description
=begin
Ruby1.9 でコードを書いている時に、 1.8 でも動くようにしとくかなぁ…
と思う時に最も困るのが個人的には String#[] の挙動の変化なのですが、
1.9 の ord, getbyte, setbyte を backport しておくわけにはいけないもんでしょうか。
Index: string.c¶
--- string.c (revision 20448)
+++ string.c (working copy)
@@ -2473,6 +2473,51 @@
/*
- call-seq:
-
-
str.getbyte(index) => 0 .. 255
-
-
-
- returns the indexth byte as an integer.
- */
+static VALUE
+rb_str_getbyte(VALUE str, VALUE index)
+{ - long pos = NUM2LONG(index);
- if (pos < 0)
- pos += RSTRING_LEN(str);
- if (pos < 0 || RSTRING_LEN(str) <= pos)
- return Qnil;
- return INT2FIX((unsigned char)RSTRING_PTR(str)[pos]);
+}
+/*
-
- call-seq:
-
-
str.setbyte(index, int) => int
-
-
-
- modifies the indexth byte as int.
- */
+static VALUE
+rb_str_setbyte(VALUE str, VALUE index, VALUE value)
+{ - long pos = NUM2LONG(index);
- int byte = NUM2INT(value);
- rb_str_modify(str);
- if (pos < -RSTRING_LEN(str) || RSTRING_LEN(str) <= pos)
- rb_raise(rb_eIndexError, "index %ld out of string", pos);
- if (pos < 0)
- pos += RSTRING_LEN(str);
- RSTRING_PTR(str)[pos] = byte;
- return value;
+}
+/*
-
- call-seq:
-
str.reverse => new_str
- Returns a new string with the characters from str in reverse order.
@@ -4556,6 +4601,24 @@
/*
- call-seq:
-
-
str.ord => integer
-
-
-
- Return the
Integer
ordinal of a one-character string.
- Return the
-
-
-
"a".ord #=> 97
-
- */
+VALUE
+rb_str_ord(VALUE s)
+{
- if (RSTRING_LEN(s) <= 0)
- rb_raise(rb_eArgError, "empty string");
- return INT2FIX(*RSTRING_PTR(s) & 0xff);
+}
+/*
-
- call-seq:
-
str.sum(n=16) => integer
- Returns a basic n-bit checksum of the characters in str,
@@ -4959,6 +5022,8 @@
rb_define_method(rb_cString, "index", rb_str_index_m, -1);
rb_define_method(rb_cString, "rindex", rb_str_rindex_m, -1);
rb_define_method(rb_cString, "replace", rb_str_replace, 1);
-
rb_define_method(rb_cString, "getbyte", rb_str_getbyte, 1);
-
rb_define_method(rb_cString, "setbyte", rb_str_setbyte, 2);
rb_define_method(rb_cString, "to_i", rb_str_to_i, -1);
rb_define_method(rb_cString, "to_f", rb_str_to_f, 0);
@@ -4987,6 +5052,7 @@
rb_define_method(rb_cString, "crypt", rb_str_crypt, 1);
rb_define_method(rb_cString, "intern", rb_str_intern, 0);
rb_define_method(rb_cString, "to_sym", rb_str_intern, 0); -
rb_define_method(rb_cString, "ord", rb_str_ord, 0);
rb_define_method(rb_cString, "include?", rb_str_include, 1);
rb_define_method(rb_cString, "start_with?", rb_str_start_with, -1);
Index: test/ruby/test_string.rb
===================================================================
--- test/ruby/test_string.rb (revision 20448)
+++ test/ruby/test_string.rb (working copy)
@@ -77,4 +77,28 @@
assert_equal("aaaaaaaaaaaa", "zzzzzzzzzzz".succ!)
assert_equal("aaaaaaaaaaaaaaaaaaaaaaaa", "zzzzzzzzzzzzzzzzzzzzzzz".succ!)
end -
def test_getbyte
-
assert_equal(0x82, "\xE3\x81\x82\xE3\x81\x84".getbyte(2))
-
assert_equal(0x82, "\xE3\x81\x82\xE3\x81\x84".getbyte(-4))
-
assert_nil("\xE3\x81\x82\xE3\x81\x84".getbyte(100))
-
end
-
def test_setbyte
-
s = "\xE3\x81\x82\xE3\x81\x84"
-
s.setbyte(2, 0x84)
-
assert_equal("\xE3\x81\x84\xE3\x81\x84", s)
-
s = "\xE3\x81\x82\xE3\x81\x84"
-
assert_raise(IndexError) { s.setbyte(100, 0) }
-
s = "\xE3\x81\x82\xE3\x81\x84"
-
s.setbyte(-4, 0x84)
-
assert_equal("\xE3\x81\x84\xE3\x81\x84", s)
-
end
-
def test_ord
-
assert_equal(0xe3, "\xE3\x81\x82\xE3\x81\x84".ord)
-
assert_raise(ArgumentError) { "".ord }
-
end
end
=end
Updated by knu (Akinori MUSHA) over 15 years ago
- Assignee set to knu (Akinori MUSHA)
=begin
ありがとうございます。これらもNEWS記載漏れですね…。
String#getbyte/setbyteはこのまま入れようと思います。
String#ordはInteger#ordのときに気づくべきでした。
こちらはmultibyte対応($KCODE aware)であるべきだと思うので、そのように直して入れます。
=end
Updated by knu (Akinori MUSHA) over 15 years ago
- Status changed from Open to Closed
- % Done changed from 0 to 100
=begin
Applied in changeset r20461.
=end
Updated by knu (Akinori MUSHA) over 15 years ago
=begin
getbyte/setbyteはほぼそのまま入れました。
ordは$KCODE対応にして入れました。
=end
Updated by shinh (Shinichiro Hamaji) over 15 years ago
=begin
浜地です。
getbyte/setbyteはほぼそのまま入れました。
ordは$KCODE対応にして入れました。
ありがとうございます。 $KCODE とか存在を忘れさっていました…
=end