[#33567] rational, complex and nuby — Tadayoshi Funaba <tadf@...>

ruby に rational と complex を組みこもうと試していて nuby という派生物

21 messages 2008/02/02

[#33580] Re: cgi.rb再構築案 — "Makoto Kuwata" <kwa@...>

桑田といいます。

17 messages 2008/02/03

[#33611] Solaris で timeout.rb が Segmentation fault する。 — shiiya@...

はじめまして。椎屋と申します。

15 messages 2008/02/06
[#33612] Re: Solaris で timeout.rb が Segmentation fault する。 — Nobuyoshi Nakada <nobu@...> 2008/02/06

なかだです。

[#33613] Re: Solaris で timeout.rb が Segmentation fault する。 — shiiya yoshitaka <shiiya@...> 2008/02/06

椎屋です。反応ありがとうございます。

[#33650] Re: Solaris で timeout.rb が Segmentation fault する。 — Nobuyoshi Nakada <nobu@...> 2008/02/08

なかだです。

[#33652] Re: Solaris で timeout.rb が Segmentation fault する。 — SATOH Fumiyasu <fumiyas@...> 2008/02/08

さとうふみやす @ OSS テクノロジです。

[#33621] EUC-KR <-> UTF-8 transition table — "Park Ji-In" <tisphie@...>

朴 芝印です。

15 messages 2008/02/06

[#33628] encdet.rb — Tanaka Akira <akr@...>

前から考えていたのですが、ファイル先頭の magic comment や

18 messages 2008/02/07

[#33662] rational, complex and mathn — Tadayoshi Funaba <tadf@...>

rational は floor、truncate、ceil、round を定義していません。Numeric

66 messages 2008/02/08
[#33663] Re: rational, complex and mathn — Tadayoshi Funaba <tadf@...> 2008/02/08

他にも問題、課題はあると思います。すぐに解決できるものと、そうでないも

[#33664] Re: rational, complex and mathn — Tadayoshi Funaba <tadf@...> 2008/02/08

ひとつ書き忘れました。

[#33707] Re: rational, complex and mathn — Yukihiro Matsumoto <matz@...> 2008/02/12

まつもと ゆきひろです

[#33714] Re: rational, complex and mathn — Tadayoshi Funaba <tadf@...> 2008/02/12

> 原さんのrationalは導入予定がありますので、この機会にもう一度

[#33727] Re: rational, complex and mathn — Shin-ichiro HARA <sinara@...> 2008/02/13

原です。

[#33761] Re: rational, complex and mathn — Tadayoshi Funaba <tadf@...> 2008/02/13

> 前にふなばさんと個人的なメールのやりとりで、結局また私がrationalをまと

[#33788] Re: rational, complex and mathn — Shin-ichiro HARA <sinara@...> 2008/02/15

原です。

[#33795] Re: rational, complex and mathn — Tadayoshi Funaba <tadf@...> 2008/02/15

> > それなりに速くはなるし、単純なところでそれなりに満足していますが、一度、

[#33806] Re: rational, complex and mathn — Tadayoshi Funaba <tadf@...> 2008/02/16

nurat 0.0.2 を出しました (ついでに nucomp も)。

[#33812] Re: rational, complex and mathn — Tadayoshi Funaba <tadf@...> 2008/02/16

仕様を確認していきたいと思います。

[#33815] Re: rational, complex and mathn — Yukihiro Matsumoto <matz@...> 2008/02/16

まつもと ゆきひろです

[#33818] Re: rational, complex and mathn — Shin-ichiro HARA <sinara@...> 2008/02/16

原です。

[#33819] Re: rational, complex and mathn — Tadayoshi Funaba <tadf@...> 2008/02/17

> > new!はRubyで実装しているためにだけ必要なので、Cで実装するな

[#33821] Re: rational, complex and mathn — Tadayoshi Funaba <tadf@...> 2008/02/17

> Rational() は、1つか2つの引数をとる。

[#33827] Re: rational, complex and mathn — Tadayoshi Funaba <tadf@...> 2008/02/17

> 実際的に重要な機能が Rational() という名前で固定されるのはクラスの定義

[#33845] Re: rational, complex and mathn — Tadayoshi Funaba <tadf@...> 2008/02/18

もうあまり手を入れないでおこうと思ったのです、つい手を入れてしまいまし

[#33886] Re: rational, complex and mathn — Tadayoshi Funaba <tadf@...> 2008/02/21

ちょっと実験してみました。原さんの rational は、かけ算割り算が速いので、

[#33888] Re: rational, complex and mathn — Tadayoshi Funaba <tadf@...> 2008/02/21

で、考えていたんですが、目的は、最速の rational を作ることではなくて、

[#33903] Re: rational, complex and mathn — Shin-ichiro HARA <sinara@...> 2008/02/22

原です。

[#33905] Re: rational, complex and mathn — "NARUSE, Yui" <naruse@...> 2008/02/22

成瀬です。

[#33908] Re: rational, complex and mathn — Yukihiro Matsumoto <matz@...> 2008/02/22

まつもと ゆきひろです

[#33914] Re: rational, complex and mathn — Tadayoshi Funaba <tadf@...> 2008/02/23

> はい。Complexについても1.9の間に組み込んでよいと思います。

[#33679] bigdecimal — Tadayoshi Funaba <tadf@...>

bigdecimal/math.rb の BigMath は、利用者が include してつかうことを前

23 messages 2008/02/09
[#33680] Re: bigdecimal — Tadayoshi Funaba <tadf@...> 2008/02/09

Integer や Float に比べると、BigDicimal() は、1 や 1.1 を受けつけない、

[#33686] Re: bigdecimal — Tadashi Saito <shiba@...2.accsnet.ne.jp> 2008/02/10

斎藤と申します。

[#33698] Re: bigdecimal — Tadayoshi Funaba <tadf@...> 2008/02/11

> 仮にBigDecimal(1.1)を、(二進小数として)受け付けると、「BigDecimalでは、

[#33705] Re: bigdecimal — Yukihiro Matsumoto <matz@...> 2008/02/12

まつもと ゆきひろです

[#33726] Re: [ruby-cvs:22680] Ruby:r15443 (trunk): * bootstraptest/runner.rb, bootstraptest/test_method.rb, enc/depend, — "U.Nakamura" <usa@...>

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

14 messages 2008/02/13
[#33730] Re: [ruby-cvs:22680] Ruby:r15443 (trunk): * bootstraptest/runner.rb, bootstraptest/test_method.rb, enc/depend, — "NARUSE, Yui" <naruse@...> 2008/02/13

成瀬です。

[#33889] Re: [ ruby-Bugs-17454 ] irb crash while iterating over all objects — Urabe Shyouhei <shyouhei@...>

卜部です。ちょっとお知恵を拝借したく。

22 messages 2008/02/21
[#33892] Re: [ ruby-Bugs-17454 ] irb crash while iterating over all objects — Nobuyoshi Nakada <nobu@...> 2008/02/21

なかだです。

[#33909] Re: [ ruby-Bugs-17454 ] irb crash while iterating over all objects — Urabe Shyouhei <shyouhei@...> 2008/02/22

Nobuyoshi Nakada さんは書きました:

[#36081] Re: [ ruby-Bugs-17454 ] irb crash while iterating over all objects — TOYOFUKU Chikanobu <nobu_toyofuku@...> 2008/09/01

豊福です。

[#36085] Re: [ ruby-Bugs-17454 ] irb crash while iterating over all objects — Yukihiro Matsumoto <matz@...> 2008/09/01

まつもと ゆきひろです

[ruby-dev:33883] patch for inspect

From: "NARUSE, Yui" <naruse@...>
Date: 2008-02-21 09:19:54 UTC
List: ruby-dev #33883
成瀬です。

懸案の inspect を、田中さんの示唆を基に変えるパッチです。

意図としては、p と irb で生の文字列が出るようにすることを第一にし、それ
以外のケースでエスケープされてしまうことはやむをえないとしました。

手法としては inspect_accumulate(str) と文字列を与え、その文字列と対象文
字列のエンコーディングが等しければそのまま、異なっていればエスケープしま
す。inspect_accumulate が定義されていなければ、それより先のオブジェクト
では inspect を用います。

-- 
NARUSE, Yui  <naruse@airemix.com>
DBDB A476 FDBD 9450 02CD 0EFC BCE3 C388 472E C1EA

Attachments (1)

inspect.patch (13.7 KB, text/x-diff)
--- array.c	(revision 15560)
+++ array.c	(working copy)
@@ -1307,23 +1307,34 @@ rb_ary_join_m(int argc, VALUE *argv, VAL
 }
 
 static VALUE
-inspect_ary(VALUE ary, VALUE dummy, int recur)
+inspect_ary(VALUE ary, VALUE result, int recur)
 {
     int tainted = OBJ_TAINTED(ary);
     long i;
-    VALUE s, str;
 
-    if (recur) return rb_tainted_str_new2("[...]");
-    str = rb_str_buf_new2("[");
+    if (recur) return rb_str_buf_cat_ascii(result, "[...]");
+    rb_str_buf_cat_ascii(result, "[");
     for (i=0; i<RARRAY_LEN(ary); i++) {
-	s = rb_inspect(RARRAY_PTR(ary)[i]);
-	if (OBJ_TAINTED(s)) tainted = Qtrue;
-	if (i > 0) rb_str_buf_cat2(str, ", ");
-	rb_str_buf_append(str, s);
-    }
-    rb_str_buf_cat2(str, "]");
-    if (tainted) OBJ_TAINT(str);
-    return str;
+	if (i > 0) rb_str_buf_cat_ascii(result, ", ");
+	rb_inspect_accumulate(RARRAY_PTR(ary)[i], result);
+    }
+    rb_str_buf_cat_ascii(result, "]");
+    OBJ_INFECT(result, ary);
+    return result;
+}
+
+/*
+ *  call-seq:
+ *     array.inspect_accumulate(str)  -> string
+ *
+ *  Create a printable version of <i>array</i>.
+ */
+
+static VALUE
+rb_ary_inspect_accumulate(VALUE ary, VALUE result)
+{
+    if (RARRAY_LEN(ary) == 0) return rb_str_buf_cat_ascii(result, "[]");
+    return rb_exec_recursive(inspect_ary, ary, result);
 }
 
 /*
@@ -1337,8 +1348,7 @@ inspect_ary(VALUE ary, VALUE dummy, int 
 static VALUE
 rb_ary_inspect(VALUE ary)
 {
-    if (RARRAY_LEN(ary) == 0) return rb_usascii_str_new2("[]");
-    return rb_exec_recursive(inspect_ary, ary, 0);
+    return rb_ary_inspect_accumulate(ary, rb_str_buf_new(0));
 }
 
 VALUE
@@ -3221,6 +3231,7 @@ Init_Array(void)
 
     rb_define_method(rb_cArray, "to_s", rb_ary_inspect, 0);
     rb_define_method(rb_cArray, "inspect", rb_ary_inspect, 0);
+    rb_define_method(rb_cArray, "inspect_accumulate", rb_ary_inspect_accumulate, 1);
     rb_define_method(rb_cArray, "to_a", rb_ary_to_a, 0);
     rb_define_method(rb_cArray, "to_ary", rb_ary_to_ary_m, 0);
     rb_define_method(rb_cArray, "frozen?",  rb_ary_frozen_p, 0);
--- hash.c	(revision 15560)
+++ hash.c	(working copy)
@@ -1145,37 +1145,50 @@ rb_hash_to_a(VALUE hash)
 }
 
 static int
-inspect_i(VALUE key, VALUE value, VALUE str)
+inspect_i(VALUE key, VALUE value, VALUE result)
 {
     VALUE str2;
 
     if (key == Qundef) return ST_CONTINUE;
-    if (RSTRING_LEN(str) > 1) {
-	rb_str_cat2(str, ", ");
+    if (*(RSTRING_END(result)-1) != '{') {
+	rb_str_buf_cat_ascii(result, ", ");
     }
-    str2 = rb_inspect(key);
-    rb_str_buf_append(str, str2);
-    OBJ_INFECT(str, str2);
-    rb_str_buf_cat2(str, "=>");
-    str2 = rb_inspect(value);
-    rb_str_buf_append(str, str2);
-    OBJ_INFECT(str, str2);
+    rb_inspect_accumulate(key, result);
+    rb_str_buf_cat_ascii(result, "=>");
+    rb_inspect_accumulate(value, result);
 
     return ST_CONTINUE;
 }
 
 static VALUE
-inspect_hash(VALUE hash, VALUE dummy, int recur)
+inspect_hash(VALUE hash, VALUE result, int recur)
 {
-    VALUE str;
 
-    if (recur) return rb_usascii_str_new2("{...}");
-    str = rb_str_buf_new2("{");
-    rb_hash_foreach(hash, inspect_i, str);
-    rb_str_buf_cat2(str, "}");
-    OBJ_INFECT(str, hash);
+    if (recur) return rb_str_buf_cat_ascii(result, "{...}");
+    rb_str_buf_cat_ascii(result, "{");
+    rb_hash_foreach(hash, inspect_i, result);
+    rb_str_buf_cat_ascii(result, "}");
+    OBJ_INFECT(result, hash);
+    return result;
+}
 
-    return str;
+/*
+ * call-seq:
+ *   hsh.to_s   => string
+ *   hsh.inspect  => string
+ *
+ * Return the contents of this hash as a string.
+ *
+ *     h = { "c" => 300, "a" => 100, "d" => 400, "c" => 300  }
+ *     h.to_s   #=> "{\"a\"=>100, \"c\"=>300, \"d\"=>400}"
+ */
+
+static VALUE
+rb_hash_inspect_accumulate(VALUE hash, VALUE result)
+{
+    if (RHASH_EMPTY_P(hash))
+	return rb_str_buf_cat_ascii(result, "{}");
+    return rb_exec_recursive(inspect_hash, hash, result);
 }
 
 /*
@@ -1192,9 +1205,7 @@ inspect_hash(VALUE hash, VALUE dummy, in
 static VALUE
 rb_hash_inspect(VALUE hash)
 {
-    if (RHASH_EMPTY_P(hash))
-	return rb_usascii_str_new2("{}");
-    return rb_exec_recursive(inspect_hash, hash, 0);
+    return rb_hash_inspect_accumulate(hash, rb_str_buf_new(0));
 }
 
 /*
@@ -2560,6 +2571,7 @@ Init_Hash(void)
     rb_define_method(rb_cHash,"to_a", rb_hash_to_a, 0);
     rb_define_method(rb_cHash,"to_s", rb_hash_inspect, 0);
     rb_define_method(rb_cHash,"inspect", rb_hash_inspect, 0);
+    rb_define_method(rb_cHash,"inspect_accumulate", rb_hash_inspect_accumulate, 1);
 
     rb_define_method(rb_cHash,"==", rb_hash_equal, 1);
     rb_define_method(rb_cHash,"[]", rb_hash_aref, 1);
--- io.c	(revision 15560)
+++ io.c	(working copy)
@@ -4556,7 +4556,10 @@ rb_f_puts(int argc, VALUE *argv)
 void
 rb_p(VALUE obj) /* for debug print within C code */
 {
-    rb_io_write(rb_stdout, rb_obj_as_string(rb_inspect(obj)));
+    VALUE str = rb_str_buf_new(0);
+    rb_enc_associate(str, rb_default_external_encoding());
+    rb_inspect_accumulate(obj, str);
+    rb_io_write(rb_stdout, str);
     rb_io_write(rb_stdout, rb_default_rs);
 }
 
--- lib/irb.rb	(revision 15560)
+++ lib/irb.rb	(working copy)
@@ -298,7 +298,7 @@ module IRB
 
     def output_value
       if @context.inspect?
-        printf @context.return_format, @context.last_value.inspect
+        printf @context.return_format, @context.last_value.inspect_accumulate("".force_encoding(Encoding.default_external))
       else
         printf @context.return_format, @context.last_value
       end
--- object.c	(revision 15560)
+++ object.c	(working copy)
@@ -32,7 +32,7 @@ VALUE rb_cNilClass;
 VALUE rb_cTrueClass;
 VALUE rb_cFalseClass;
 
-static ID id_eq, id_eql, id_match, id_inspect, id_init_copy;
+static ID id_eq, id_eql, id_match, id_inspect, id_inspect_accumulate, id_init_copy;
 
 /*
  *  call-seq:
@@ -313,6 +313,12 @@ rb_inspect(VALUE obj)
     return rb_obj_as_string(rb_funcall(obj, id_inspect, 0, 0));
 }
 
+VALUE
+rb_inspect_accumulate(VALUE obj, VALUE result)
+{
+    return rb_obj_as_string(rb_funcall(obj, id_inspect_accumulate, 1, result));
+}
+
 static int
 inspect_i(ID id, VALUE value, VALUE str)
 {
@@ -324,16 +330,15 @@ inspect_i(ID id, VALUE value, VALUE str)
     if (!rb_is_instance_id(id)) return ST_CONTINUE;
     if (RSTRING_PTR(str)[0] == '-') { /* first element */
 	RSTRING_PTR(str)[0] = '#';
-	rb_str_cat2(str, " ");
+	rb_str_buf_cat_ascii(str, " ");
     }
     else {
-	rb_str_cat2(str, ", ");
+	rb_str_buf_cat_ascii(str, ", ");
     }
     ivname = rb_id2name(id);
     rb_str_cat2(str, ivname);
-    rb_str_cat2(str, "=");
-    str2 = rb_inspect(value);
-    rb_str_append(str, str2);
+    rb_str_buf_cat_ascii(str, "=");
+    rb_inspect_accumulate(value, str);
     OBJ_INFECT(str, str2);
 
     return ST_CONTINUE;
@@ -343,18 +348,67 @@ static VALUE
 inspect_obj(VALUE obj, VALUE str, int recur)
 {
     if (recur) {
-	rb_str_cat2(str, " ...");
+	rb_str_buf_cat_ascii(str, " ...");
     }
     else {
 	rb_ivar_foreach(obj, inspect_i, str);
     }
-    rb_str_cat2(str, ">");
+    rb_str_buf_cat_ascii(str, ">");
     RSTRING_PTR(str)[0] = '#';
     OBJ_INFECT(str, obj);
 
     return str;
 }
 
+static VALUE
+obj_ivar_inspect(VALUE obj, VALUE result)
+{
+    int has_ivar = 0;
+    VALUE *ptr = ROBJECT_PTR(obj);
+    long len = ROBJECT_LEN(obj);
+    long i;
+
+    for (i = 0; i < len; i++) {
+	if (ptr[i] != Qundef) {
+	    has_ivar = 1;
+	    break;
+	}
+    }
+
+    if (has_ivar) {
+	char *c;
+
+	c = rb_obj_classname(obj);
+	rb_str_append(result, rb_sprintf("-<%s:%p", c, (void*)obj));
+	return rb_exec_recursive(inspect_obj, obj, result);
+    }
+    return 0;
+}
+
+/*
+ *  call-seq:
+ *     obj.inspect_accumulate(str)   => string
+ *  
+ *  Returns a string containing a human-readable representation of
+ *  <i>obj</i>. If not overridden, uses the <code>to_s</code> method to
+ *  generate the string.
+ */
+
+static VALUE
+rb_obj_inspect_accumulate(VALUE obj, VALUE result)
+{
+    if (TYPE(obj) == T_OBJECT) {
+	VALUE meth = rb_obj_method(obj, ID2SYM(id_inspect));
+	VALUE owner = rb_funcall(meth, rb_intern("owner"), 0, 0);
+	if (owner == rb_mKernel) {
+	    VALUE str = obj_ivar_inspect(obj, result);
+	    if (str)
+		return str;
+	}
+    }
+    return rb_str_append(result, rb_funcall(obj, id_inspect, 0, 0));
+}
+
 /*
  *  call-seq:
  *     obj.inspect   => string
@@ -367,37 +421,17 @@ inspect_obj(VALUE obj, VALUE str, int re
  *     Time.new.inspect                 #=> "Wed Apr 09 08:54:39 CDT 2003"
  */
 
-
 static VALUE
 rb_obj_inspect(VALUE obj)
 {
-
     if (TYPE(obj) == T_OBJECT) {
-        int has_ivar = 0;
-        VALUE *ptr = ROBJECT_PTR(obj);
-        long len = ROBJECT_LEN(obj);
-        long i;
-
-        for (i = 0; i < len; i++) {
-            if (ptr[i] != Qundef) {
-                has_ivar = 1;
-                break;
-            }
-        }
-
-        if (has_ivar) {
-            VALUE str;
-            char *c;
-
-            c = rb_obj_classname(obj);
-            str = rb_sprintf("-<%s:%p", c, (void*)obj);
-            return rb_exec_recursive(inspect_obj, obj, str);
-        }
+        VALUE str = obj_ivar_inspect(obj, rb_str_buf_new(0));
+        if (str)
+	    return str;
     }
     return rb_funcall(obj, rb_intern("to_s"), 0, 0);
 }
 
-
 /*
  *  call-seq:
  *     obj.instance_of?(class)    => true or false
@@ -2403,6 +2437,7 @@ Init_Object(void)
 
     rb_define_method(rb_mKernel, "to_s", rb_any_to_s, 0);
     rb_define_method(rb_mKernel, "inspect", rb_obj_inspect, 0);
+    rb_define_method(rb_mKernel, "inspect_accumulate", rb_obj_inspect_accumulate, 1);
     rb_define_method(rb_mKernel, "methods", rb_obj_methods, -1);
     rb_define_method(rb_mKernel, "singleton_methods", rb_obj_singleton_methods, -1); /* in class.c */
     rb_define_method(rb_mKernel, "protected_methods", rb_obj_protected_methods, -1);
@@ -2524,5 +2559,6 @@ Init_Object(void)
     id_eql = rb_intern("eql?");
     id_match = rb_intern("=~");
     id_inspect = rb_intern("inspect");
+    id_inspect_accumulate = rb_intern("inspect_accumulate");
     id_init_copy = rb_intern("initialize_copy");
 }
--- string.c	(revision 15560)
+++ string.c	(working copy)
@@ -3639,24 +3639,19 @@ prefix_escape(VALUE str, int c, rb_encod
 
 /*
  * call-seq:
- *   str.inspect   => string
+ *   str.inspect_accumulate(str)   => string
  *
  * Returns a printable version of _str_, surrounded by quote marks,
  * with special characters escaped.
- *
- *    str = "hello"
- *    str[3] = "\b"
- *    str.inspect       #=> "\"hel\bo\""
  */
 
 VALUE
-rb_str_inspect(VALUE str)
+rb_str_inspect_accumulate(VALUE str, VALUE result)
 {
-    rb_encoding *enc = STR_ENC_GET(str);
+    rb_encoding *enc = STR_ENC_GET(result);
     char *p, *pend;
-    VALUE result = rb_str_buf_new2("");
 
-    rb_enc_associate(result, enc);
+    if (!enc || enc != STR_ENC_GET(str)) enc = rb_usascii_encoding();
     str_cat_char(result, '"', enc);
     p = RSTRING_PTR(str); pend = RSTRING_END(str);
     while (p < pend) {
@@ -3731,6 +3726,23 @@ rb_str_inspect(VALUE str)
     OBJ_INFECT(result, str);
     return result;
 }
+/*
+ * call-seq:
+ *   str.inspect   => string
+ *
+ * Returns a printable version of _str_, surrounded by quote marks,
+ * with special characters escaped.
+ *
+ *    str = "hello"
+ *    str[3] = "\b"
+ *    str.inspect       #=> "\"hel\bo\""
+ */
+
+VALUE
+rb_str_inspect(VALUE str)
+{
+    return rb_str_inspect_accumulate(str, rb_str_buf_new(0));
+}
 
 #define IS_EVSTR(p,e) ((p) < (e) && (*(p) == '$' || *(p) == '@' || *(p) == '{'))
 
@@ -6427,6 +6439,7 @@ Init_String(void)
     rb_define_method(rb_cString, "to_s", rb_str_to_s, 0);
     rb_define_method(rb_cString, "to_str", rb_str_to_s, 0);
     rb_define_method(rb_cString, "inspect", rb_str_inspect, 0);
+    rb_define_method(rb_cString, "inspect_accumulate", rb_str_inspect_accumulate, 1);
     rb_define_method(rb_cString, "dump", rb_str_dump, 0);
 
     rb_define_method(rb_cString, "upcase", rb_str_upcase, 0);
--- struct.c	(revision 15560)
+++ struct.c	(working copy)
@@ -477,45 +477,59 @@ rb_struct_each_pair(VALUE s)
 }
 
 static VALUE
-inspect_struct(VALUE s, VALUE dummy, int recur)
+inspect_struct(VALUE s, VALUE result, int recur)
 {
     char *cname = rb_class2name(rb_obj_class(s));
-    VALUE str, members;
+    VALUE members;
     long i;
 
     if (recur) {
-	return rb_sprintf("#<struct %s:...>", cname);
+	return rb_str_append(result, rb_sprintf("#<struct %s:...>", cname));
     }
 
     members = rb_struct_members(s);
     if (cname[0] == '#') {
-	str = rb_str_new2("#<struct ");
+	rb_str_buf_cat_ascii(result, "#<struct ");
     }
     else {
-	str = rb_sprintf("#<struct %s ", cname);
+	rb_str_append(result, rb_sprintf("#<struct %s ", cname));
     }
     for (i=0; i<RSTRUCT_LEN(s); i++) {
 	VALUE slot;
 	ID id;
 
 	if (i > 0) {
-	    rb_str_cat2(str, ", ");
+	    rb_str_buf_cat_ascii(result, ", ");
 	}
 	slot = RARRAY_PTR(members)[i];
 	id = SYM2ID(slot);
 	if (rb_is_local_id(id) || rb_is_const_id(id)) {
-	    rb_str_append(str, rb_id2str(id));
+	    rb_str_append(result, rb_id2str(id));
 	}
 	else {
-	    rb_str_append(str, rb_inspect(slot));
+	    rb_str_append(result, rb_inspect_accumulate(slot));
 	}
-	rb_str_cat2(str, "=");
-	rb_str_append(str, rb_inspect(RSTRUCT_PTR(s)[i]));
+	rb_str_buf_cat_ascii(result, "=");
+	rb_str_append(result, rb_inspect_accumulate(RSTRUCT_PTR(s)[i]));
     }
-    rb_str_cat2(str, ">");
-    OBJ_INFECT(str, s);
+    rb_str_buf_cat_ascii(result, ">");
+    OBJ_INFECT(result, s);
+
+    return result;
+}
+
+/*
+ * call-seq:
+ *   struct.to_s      => string
+ *   struct.inspect   => string
+ *
+ * Describe the contents of this struct in a string.
+ */
 
-    return str;
+static VALUE
+rb_struct_inspect_accumulate(VALUE s, VALUE result)
+{
+    return rb_exec_recursive(inspect_struct, s, result);
 }
 
 /*
@@ -529,7 +543,7 @@ inspect_struct(VALUE s, VALUE dummy, int
 static VALUE
 rb_struct_inspect(VALUE s)
 {
-    return rb_exec_recursive(inspect_struct, s, 0);
+    return rb_struct_inspect_accumulate(s, rb_str_buf_new(0));
 }
 
 /*

In This Thread

Prev Next