[Feature:trunk] hide the internal of anonymous Enumerator

e$B1sF#$G$9!#e(B

[ruby-dev:39665] e$B$h$j0zMQ!#e(B

2009e$BG/e(B11e$B7ne(B12e$BF|e(B0:38 Akinori MUSHA [email protected]:

e$B!!e(BYielder/Generator e$B$H$$$&AH9g$;$K$h$k<BAu$O<B83E*$J$b$N$G!“FC$Ke(B
e$B8e<T$O30It$K8x3+$9$kI,MW$,$J$$$N$G4:$($FIz$;$F$$$^$7$?!#8x3+;EMM$Ke(B
[email protected])Ls$K$J$k$N$G!”<{MW$,@8$8$k$^$G$OHs8x3+$NJ}$,$$$$$N$G$O$J$$e(B
e$B$G$7$g$&$+!#e(B

e$B$H$$$&$3$H$J$i!"$J$k$Y$/FbIt<BAu$r%f!<%6$+$i8+$($J$$$h$&$K$7$^$;$s$+!)e(B

  • Enumerator::Generator e$B$rF?L>%/%i%9$K$9$ke(B (ARGF e$B$N$h$&$Ke(B)
  • Generator.new e$B$de(B Yielder.new e$B$r6X;_$9$ke(B
  • Enumerator#inspect e$B$Ge(B Generator e$B$NB8:_$O1#$9e(B

e$B$H$9$k%Q%C%A$r=q$$$F$_$^$7$?!#$I$&$G$7$g$&!#e(B

diff --git a/enumerator.c b/enumerator.c
index 7c50f3d…88c37fd 100644
— a/enumerator.c
+++ b/enumerator.c
@@ -886,29 +886,34 @@ inspect_enumerator(VALUE obj, VALUE dummy, int
recur)
untrusted = OBJ_UNTRUSTED(eobj);

 /* (1..100).each_cons(2) => "#<Enumerator: 1..100:each_cons(2)>" */
  • str = rb_sprintf("#<%s: ", cname);
  • rb_str_concat(str, rb_inspect(eobj));
  • rb_str_buf_cat2(str, “:”);
  • rb_str_buf_cat2(str, rb_id2name(e->meth));
  • if (rb_obj_is_kind_of(eobj, rb_cGenerator)) {
  • str = rb_sprintf("#<%s:%p>", cname, (void*)eobj);
  • }
  • else {
  • str = rb_sprintf("#<%s: ", cname);
  • rb_str_concat(str, rb_inspect(eobj));
  • rb_str_buf_cat2(str, “:”);
  • rb_str_buf_cat2(str, rb_id2name(e->meth));
  • if (e->args) {
  • long argc = RARRAY_LEN(e->args);
  • VALUE *argv = RARRAY_PTR(e->args);
  •    if (e->args) {
    
  •  long   argc = RARRAY_LEN(e->args);
    
  •  VALUE *argv = RARRAY_PTR(e->args);
    
  • rb_str_buf_cat2(str, “(”);
  •  rb_str_buf_cat2(str, "(");
    
  • while (argc–) {
  •  VALUE arg = *argv++;
    
  •  while (argc--) {
    
  • VALUE arg = *argv++;
  •  rb_str_concat(str, rb_inspect(arg));
    
  •  rb_str_buf_cat2(str, argc > 0 ? ", " : ")");
    
  • rb_str_concat(str, rb_inspect(arg));
  • rb_str_buf_cat2(str, argc > 0 ? ", " : “)”);
  •  if (OBJ_TAINTED(arg)) tainted = TRUE;
    
  •  if (OBJ_UNTRUSTED(arg)) untrusted = TRUE;
    
  • }
  • }
  • if (OBJ_TAINTED(arg)) tainted = TRUE;
  • if (OBJ_UNTRUSTED(arg)) untrusted = TRUE;
  •  }
    
  •    }
    
  • rb_str_buf_cat2(str, “>”);
  • rb_str_buf_cat2(str, “>”);

  • }

    if (tainted) OBJ_TAINT(str);
    if (untrusted) OBJ_UNTRUST(str);
    @@ -1223,17 +1228,17 @@ Init_Enumerator(void)
    rb_define_method(rb_eStopIteration, “result”, stop_result, 0);

    /* Generator */

  • rb_cGenerator = rb_define_class_under(rb_cEnumerator,
    “Generator”, rb_cObject);
  • rb_cGenerator = rb_class_new(rb_cObject);
  • rb_undef_alloc_func(rb_cGenerator);
  • rb_set_class_path(rb_cGenerator, rb_cObject,
    “Enumerator::Generator”);
    rb_include_module(rb_cGenerator, rb_mEnumerable);
  • rb_define_alloc_func(rb_cGenerator, generator_allocate);
  • rb_define_method(rb_cGenerator, “initialize”, generator_initialize,
    -1);
  • rb_define_method(rb_cGenerator, “initialize_copy”,
    generator_init_copy, 1);
    rb_define_method(rb_cGenerator, “each”, generator_each, 0);
  • rb_obj_freeze(rb_cGenerator);

  • rb_gc_register_mark_object(rb_cGenerator);

    /* Yielder */
    rb_cYielder = rb_define_class_under(rb_cEnumerator, “Yielder”,
    rb_cObject);

  • rb_define_alloc_func(rb_cYielder, yielder_allocate);
  • rb_define_method(rb_cYielder, “initialize”, yielder_initialize, 0);
  • rb_undef_alloc_func(rb_cYielder);
    rb_define_method(rb_cYielder, “yield”, yielder_yield, -2);
    rb_define_method(rb_cYielder, “<<”, yielder_yield_push, -2);

At Thu, 12 Nov 2009 20:53:54 +0900,
Yusuke ENDOH wrote:

  • Enumerator::Generator を匿名クラスにする (ARGF のように)
  • Generator.new ã‚„ Yielder.new を禁止する
  • Enumerator#inspect で Generator ã®å­˜åœ¨ã¯éš ã™

とするパッチを書いてみました。どうでしょう。

 そこまでする必要はないかと思っていたんですが、どうでしょうね。
いじられてSEGVã™ã‚‹ã‚ˆã†ãªã‚‚ã®ã§ãªã‘ã‚Œã°ã€ãƒ‡ãƒãƒƒã‚°ã®ãŸã‚ã«ã¯éš ã—
すぎない方がいいんじゃないかとか、互換性は保証しないけどそれを
敢えて使って実験的なライブラリを書く自由までは奪いたくないとか、
そういう考えもあるんですよね。まあ、一言で言うと私の都合ですが。

 とはいえ、undocumentedであっても見えると一般利用されて、それが
メジャーになると、互換性を崩すとruby側に文句が来たりするかなあ。
難しいですね…。

e$B%A%1%C%He(B #2360 e$B$,99?7$5$l$^$7$?!#e(B (by Yusuke E.)

e$B%9%F!<%?%9e(B Assignede$B$+$ie(BRejectede$B$KJQ99e(B

e$B1sF#$G$9!#e(B

  • Enumerator::Generator e$B$rF?L>%/%i%9$K$9$ke(B (ARGF e$B$N$h$&$Ke(B)
  • Generator.new e$B$de(B Yielder.new e$B$r6X;_$9$ke(B
  • Enumerator#inspect e$B$Ge(B Generator e$B$NB8:_$O1#$9e(B

e$B$H$9$k%Q%C%A$r=q$$$F$_$^$7$?!#$I$&$G$7$g$&!#e(B

[ruby-dev:39685] e$B$GDs0F$7$F$$$ke(B private constant
e$B$G2r7h$9$kJ}$,e(B
e$B$$$$$H;W$&$N$G!"$3$N%A%1%C%H$O<+J,$Ge(B reject e$B$7$^$9!#e(B

e$B$A$J$_$Ke(B private constant e$B$NDs0F$O!"e(B1.9.2
e$B%j%j!<%9$NAK32MW0x$Ke(B
e$B$J$C$?$i7y$J$N$G!"e(B1.9.3 e$B$G$NF3F~$rL;X$9$3$H$K$7$^$7$?!#e(B


Yusuke E. [email protected]

http://redmine.ruby-lang.org/issues/show/2360