|
View:
New views
2 Messages
—
Rating Filter:
Alert me
|
|
|
[ruby-dev:39671] [Feature:trunk] hide the internal of anonymous Enumerator遠藤です。
[ruby-dev:39665] より引用。 2009年11月12日0:38 Akinori MUSHA <knu@...>: > Yielder/Generator という組合せによる実装は実験的なもので、特に > 後者は外部に公開する必要がないので敢えて伏せていました。公開仕様に > すると制約になるので、需要が生じるまでは非公開の方がいいのではない > でしょうか。 ということなら、なるべく内部実装をユーザから見えないようにしませんか? - Enumerator::Generator を匿名クラスにする (ARGF のように) - Generator.new や Yielder.new を禁止する - Enumerator#inspect で Generator の存在は隠す とするパッチを書いてみました。どうでしょう。 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); -- Yusuke ENDOH <mame@...> |
|
|
[ruby-dev:39674] Re: [Feature:trunk] hide the internal of anonymous EnumeratorAt Thu, 12 Nov 2009 20:53:54 +0900,
Yusuke ENDOH wrote: > [ruby-dev:39665] より引用。 > > 2009年11月12日0:38 Akinori MUSHA <knu@...>: > > Yielder/Generator という組合せによる実装は実験的なもので、特に > > 後者は外部に公開する必要がないので敢えて伏せていました。公開仕様に > > すると制約になるので、需要が生じるまでは非公開の方がいいのではない > > でしょうか。 > > ということなら、なるべく内部実装をユーザから見えないようにしませんか? > > - Enumerator::Generator を匿名クラスにする (ARGF のように) > - Generator.new や Yielder.new を禁止する > - Enumerator#inspect で Generator の存在は隠す > > とするパッチを書いてみました。どうでしょう。 いじられてSEGVするようなものでなければ、デバッグのためには隠し すぎない方がいいんじゃないかとか、互換性は保証しないけどそれを 敢えて使って実験的なライブラリを書く自由までは奪いたくないとか、 そういう考えもあるんですよね。まあ、一言で言うと私の都合ですが。 とはいえ、undocumentedであっても見えると一般利用されて、それが メジャーになると、互換性を崩すとruby側に文句が来たりするかなあ。 難しいですね…。 -- Akinori MUSHA / http://akinori.org/ |
| Free embeddable forum powered by Nabble | Forum Help |