[#37248] [Feature:1.9] Enumerator#inspect — "Yusuke ENDOH" <mame@...>

遠藤です。

12 messages 2008/12/02

[#37337] [Feature #841] Object#self — "rubikitch ." <redmine@...>

Feature #841: Object#self

13 messages 2008/12/09

[#37513] Current status of 1.9.1 RC1's issues — "Yugui (Yuki Sonoda)" <yugui@...>

Hi, folks

14 messages 2008/12/20
[#37516] Re: Current status of 1.9.1 RC1's issues — Masatoshi SEKI <m_seki@...> 2008/12/20

咳といいます。

[#37576] [BUG:trunk] encoding for stdio's — "Yugui (Yuki Sonoda)" <yugui@...>

Yuguiです。

11 messages 2008/12/24

[ruby-dev:37248] [Feature:1.9] Enumerator#inspect

From: "Yusuke ENDOH" <mame@...>
Date: 2008-12-02 14:59:52 UTC
List: ruby-dev #37248
遠藤です。

Enumerator の中身をわかりやすく表示してくれる Enumerator#inspect を
提供すると便利だと思います。例えばこんな感じ。

$ ruby19 -e 'g = (1..1000).each; p g'
#<Enumerator:[1, 2, 3, ...(snipped)]>

現状は #<Enumerator:0x8269654> とかなので、デバッグには不便です。

以下はたたき台のパッチです。


Index: enumerator.c
===================================================================
--- enumerator.c	(revision 20448)
+++ enumerator.c	(working copy)
@@ -545,7 +545,69 @@
     return obj;
 }

+static VALUE
+inspect_enumerator_i(VALUE val, VALUE *memo)
+{
+    VALUE str = memo[0];
+    if (memo[1] >= 3) {
+	rb_str_buf_cat2(str, ", ...(snipped)");
+	rb_iter_break();
+    }
+    if (memo[1] > 0) rb_str_buf_cat2(str, ", ");
+    rb_str_buf_append(str, rb_inspect(val));
+    memo[1]++;
+    if (OBJ_TAINTED(val)) memo[2] = Qtrue;
+    if (OBJ_UNTRUSTED(val)) memo[3] = Qtrue;
+    return Qnil;
+}
+
+static VALUE
+inspect_enumerator(VALUE obj, VALUE dummy, int recur)
+{
+    const char *cname = rb_obj_classname(obj);
+    struct enumerator *e;
+    int argc = 0;
+    VALUE *argv = 0;
+    VALUE str;
+    VALUE memo[4];
+
+    if (recur) {
+	str = rb_sprintf("#<%s:[...]>", cname);
+	OBJ_TAINT(str);
+	return str;
+    }
+
+    memo[0] = str = rb_sprintf("#<%s:[", cname);
+    memo[1] = (VALUE)0;
+    memo[2] = OBJ_TAINTED(obj);
+    memo[3] = OBJ_UNTRUSTED(obj);
+    e = enumerator_ptr(obj);
+    if (e->args) {
+	argc = RARRAY_LEN(e->args);
+	argv = RARRAY_PTR(e->args);
+    }
+    rb_block_call(e->obj, e->meth, argc, argv,
+		  inspect_enumerator_i, (VALUE)memo);
+    rb_str_buf_cat2(str, "]>");
+    if (memo[2]) OBJ_TAINT(str);
+    if (memo[3]) OBJ_UNTRUST(str);
+    return str;
+}
+
 /*
+ * call-seq:
+ *   e.inspect  => "#<Enumerator:[1, 2, 3, ...(snipped)]>"
+ *
+ *  Create a printable version of <i>e</i>.
+ */
+
+static VALUE
+enumerator_inspect(VALUE obj)
+{
+    return rb_exec_recursive(inspect_enumerator, obj, 0);
+}
+
+/*
  * Yielder
  */
 static void
@@ -779,6 +841,7 @@
     rb_define_method(rb_cEnumerator, "with_object", enumerator_with_object, 1);
     rb_define_method(rb_cEnumerator, "next", enumerator_next, 0);
     rb_define_method(rb_cEnumerator, "rewind", enumerator_rewind, 0);
+    rb_define_method(rb_cEnumerator, "inspect", enumerator_inspect, 0);

     rb_eStopIteration = rb_define_class("StopIteration", rb_eIndexError);

Index: lib/pp.rb
===================================================================
--- lib/pp.rb	(revision 20448)
+++ lib/pp.rb	(working copy)
@@ -339,6 +339,27 @@
   end
 end

+class Enumerator
+  def pretty_print(q)
+    s =  self.class.to_s
+    q.group(s.size + 3, '#<' + s + ':', ']>') {
+      idx = 0
+      q.seplist(take(4)) {|v|
+        if idx < 3
+          q.pp v
+        else
+          q.text "...(snipped)"
+        end
+        idx += 1
+      }
+    }
+  end
+
+  def pretty_print_cycle(q)
+    q.text('#<' + self.class.to_s + ':[...]')
+  end
+end
+
 class Hash
   def pretty_print(q)
     q.pp_hash self

-- 
Yusuke ENDOH <mame@tsg.ne.jp>

In This Thread

Prev Next