diff options
author | shugo <shugo@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2012-03-24 15:17:31 +0000 |
---|---|---|
committer | shugo <shugo@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2012-03-24 15:17:31 +0000 |
commit | 6b885f6e74a48c1b43cfbce1298cda98a64fe6bc (patch) | |
tree | cd840b407e9fd41094f36af4cabb07a322632183 | |
parent | 576a69a5645c455a5faf1e1fa2205a60c7caec7f (diff) | |
download | ruby-6b885f6e74a48c1b43cfbce1298cda98a64fe6bc.tar.gz |
* enumerator (enumerator_inspect): include the original receiver and
method name of Enumerator::Lazy in the result of inspect.
[ruby-core:43345] [Bug #6159]
* enumerator (InitVM_Enumerator): don't use rb_define_alias for
some methods such as collect in order to make rb_frame_this_func()
return the correct method names.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@35124 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r-- | ChangeLog | 10 | ||||
-rw-r--r-- | enumerator.c | 89 | ||||
-rw-r--r-- | test/ruby/test_lazy_enumerator.rb | 12 |
3 files changed, 86 insertions, 25 deletions
@@ -1,3 +1,13 @@ +Sat Mar 24 23:59:00 2012 Shugo Maeda <shugo@ruby-lang.org> + + * enumerator (enumerator_inspect): include the original receiver and + method name of Enumerator::Lazy in the result of inspect. + [ruby-core:43345] [Bug #6159] + + * enumerator (InitVM_Enumerator): don't use rb_define_alias for + some methods such as collect in order to make rb_frame_this_func() + return the correct method names. + Sat Mar 24 22:22:18 2012 Sambasiva Rao Suda <sambasivarao@gmail.org> * time.c (time_init_1): Time.new will accept seconds as string or diff --git a/enumerator.c b/enumerator.c index 865730912f..c7d3d799e4 100644 --- a/enumerator.c +++ b/enumerator.c @@ -858,7 +858,7 @@ inspect_enumerator(VALUE obj, VALUE dummy, int recur) { struct enumerator *e; const char *cname; - VALUE eobj, str; + VALUE eobj, str, method; int tainted, untrusted; TypedData_Get_Struct(obj, struct enumerator, &enumerator_data_type, e); @@ -875,7 +875,10 @@ inspect_enumerator(VALUE obj, VALUE dummy, int recur) return str; } - eobj = e->obj; + eobj = rb_iv_get(obj, "receiver"); + if (NIL_P(eobj)) { + eobj = e->obj; + } tainted = OBJ_TAINTED(eobj); untrusted = OBJ_UNTRUSTED(eobj); @@ -883,8 +886,16 @@ inspect_enumerator(VALUE obj, VALUE dummy, int recur) /* (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)); + method = rb_iv_get(obj, "method"); + if (NIL_P(method)) { + rb_str_buf_cat2(str, ":"); + rb_str_buf_cat2(str, rb_id2name(e->meth)); + } + else if (RTEST(method)) { + Check_Type(method, T_SYMBOL); + rb_str_buf_cat2(str, ":"); + rb_str_buf_cat2(str, rb_id2name(SYM2ID(method))); + } if (e->args) { long argc = RARRAY_LEN(e->args); @@ -1237,6 +1248,29 @@ lazy_initialize(int argc, VALUE *argv, VALUE self) return self; } +static void +lazy_set_inspection_data(VALUE obj, VALUE receiver, VALUE method) +{ + rb_iv_set(obj, "receiver", receiver); + if (NIL_P(method)) { + ID id = rb_frame_this_func(); + rb_iv_set(obj, "method", ID2SYM(id)); + } + else { + rb_iv_set(obj, "method", method); + } +} + +/* + * An ugly macro to set inspection data to arg, and return arg. + * RETURN_LAZY assumes that the reciver is obj. + */ +#define RETURN_LAZY(arg) do { \ + VALUE lazy = arg; \ + lazy_set_inspection_data(lazy, obj, Qnil); \ + return lazy; \ +} while (0) + /* * call-seq: * e.lazy -> lazy_enumerator @@ -1271,7 +1305,12 @@ lazy_initialize(int argc, VALUE *argv, VALUE self) static VALUE enumerable_lazy(VALUE obj) { - return rb_class_new_instance(1, &obj, rb_cLazy); + VALUE result; + + result = rb_class_new_instance(1, &obj, rb_cLazy); + /* Qfalse indicates that the Enumerator::Lazy has no method name */ + lazy_set_inspection_data(result, obj, Qfalse); + return result; } static VALUE @@ -1290,7 +1329,7 @@ lazy_map(VALUE obj) rb_raise(rb_eArgError, "tried to call lazy map without a block"); } - return rb_block_call(rb_cLazy, id_new, 1, &obj, lazy_map_func, 0); + RETURN_LAZY(rb_block_call(rb_cLazy, id_new, 1, &obj, lazy_map_func, 0)); } static VALUE @@ -1352,7 +1391,7 @@ lazy_flat_map(VALUE obj) rb_raise(rb_eArgError, "tried to call lazy flat_map without a block"); } - return rb_block_call(rb_cLazy, id_new, 1, &obj, lazy_flat_map_func, 0); + RETURN_LAZY(rb_block_call(rb_cLazy, id_new, 1, &obj, lazy_flat_map_func, 0)); } static VALUE @@ -1373,7 +1412,7 @@ lazy_select(VALUE obj) rb_raise(rb_eArgError, "tried to call lazy select without a block"); } - return rb_block_call(rb_cLazy, id_new, 1, &obj, lazy_select_func, 0); + RETURN_LAZY(rb_block_call(rb_cLazy, id_new, 1, &obj, lazy_select_func, 0)); } static VALUE @@ -1394,7 +1433,7 @@ lazy_reject(VALUE obj) rb_raise(rb_eArgError, "tried to call lazy reject without a block"); } - return rb_block_call(rb_cLazy, id_new, 1, &obj, lazy_reject_func, 0); + RETURN_LAZY(rb_block_call(rb_cLazy, id_new, 1, &obj, lazy_reject_func, 0)); } static VALUE @@ -1424,9 +1463,9 @@ lazy_grep_iter(VALUE val, VALUE m, int argc, VALUE *argv) static VALUE lazy_grep(VALUE obj, VALUE pattern) { - return rb_block_call(rb_cLazy, id_new, 1, &obj, - rb_block_given_p() ? lazy_grep_iter : lazy_grep_func, - pattern); + RETURN_LAZY(rb_block_call(rb_cLazy, id_new, 1, &obj, + rb_block_given_p() ? lazy_grep_iter : lazy_grep_func, + pattern)); } static VALUE @@ -1473,7 +1512,7 @@ lazy_zip(int argc, VALUE *argv, VALUE obj) rb_ary_push(ary, rb_funcall(argv[i], id_lazy, 0)); } - return rb_block_call(rb_cLazy, id_new, 1, &obj, lazy_zip_func, ary); + RETURN_LAZY(rb_block_call(rb_cLazy, id_new, 1, &obj, lazy_zip_func, ary)); } static VALUE @@ -1508,8 +1547,8 @@ lazy_take(VALUE obj, VALUE n) argc = 3; } memo = NEW_MEMO(0, 0, len); - return rb_block_call(rb_cLazy, id_new, argc, argv, lazy_take_func, - (VALUE) memo); + RETURN_LAZY(rb_block_call(rb_cLazy, id_new, argc, argv, lazy_take_func, + (VALUE) memo)); } static VALUE @@ -1524,7 +1563,7 @@ lazy_take_while_func(VALUE val, VALUE args, int argc, VALUE *argv) static VALUE lazy_take_while(VALUE obj) { - return rb_block_call(rb_cLazy, id_new, 1, &obj, lazy_take_while_func, 0); + RETURN_LAZY(rb_block_call(rb_cLazy, id_new, 1, &obj, lazy_take_while_func, 0)); } static VALUE @@ -1551,8 +1590,8 @@ lazy_drop(VALUE obj, VALUE n) rb_raise(rb_eArgError, "attempt to drop negative size"); } memo = NEW_MEMO(0, 0, len); - return rb_block_call(rb_cLazy, id_new, 1, &obj, lazy_drop_func, - (VALUE) memo); + RETURN_LAZY(rb_block_call(rb_cLazy, id_new, 1, &obj, lazy_drop_func, + (VALUE) memo)); } static VALUE @@ -1575,8 +1614,8 @@ lazy_drop_while(VALUE obj) NODE *memo; memo = NEW_MEMO(0, 0, FALSE); - return rb_block_call(rb_cLazy, id_new, 1, &obj, lazy_drop_while_func, - (VALUE) memo); + RETURN_LAZY(rb_block_call(rb_cLazy, id_new, 1, &obj, lazy_drop_while_func, + (VALUE) memo)); } static VALUE @@ -1600,8 +1639,8 @@ lazy_cycle(int argc, VALUE *argv, VALUE obj) if (argc > 0) { rb_ary_cat(args, argv, argc); } - return rb_block_call(rb_cLazy, id_new, len, RARRAY_PTR(args), - lazy_cycle_func, args /* prevent from GC */); + RETURN_LAZY(rb_block_call(rb_cLazy, id_new, len, RARRAY_PTR(args), + lazy_cycle_func, args /* prevent from GC */)); } static VALUE @@ -1693,8 +1732,11 @@ InitVM_Enumerator(void) rb_define_method(rb_mEnumerable, "lazy", enumerable_lazy, 0); rb_define_method(rb_cLazy, "initialize", lazy_initialize, -1); rb_define_method(rb_cLazy, "map", lazy_map, 0); + rb_define_method(rb_cLazy, "collect", lazy_map, 0); rb_define_method(rb_cLazy, "flat_map", lazy_flat_map, 0); + rb_define_method(rb_cLazy, "collect_concat", lazy_flat_map, 0); rb_define_method(rb_cLazy, "select", lazy_select, 0); + rb_define_method(rb_cLazy, "find_all", lazy_select, 0); rb_define_method(rb_cLazy, "reject", lazy_reject, 0); rb_define_method(rb_cLazy, "grep", lazy_grep, 1); rb_define_method(rb_cLazy, "zip", lazy_zip, -1); @@ -1705,9 +1747,6 @@ InitVM_Enumerator(void) rb_define_method(rb_cLazy, "cycle", lazy_cycle, -1); rb_define_method(rb_cLazy, "lazy", lazy_lazy, 0); - rb_define_alias(rb_cLazy, "collect", "map"); - rb_define_alias(rb_cLazy, "collect_concat", "flat_map"); - rb_define_alias(rb_cLazy, "find_all", "select"); rb_define_alias(rb_cLazy, "force", "to_a"); rb_eStopIteration = rb_define_class("StopIteration", rb_eIndexError); diff --git a/test/ruby/test_lazy_enumerator.rb b/test/ruby/test_lazy_enumerator.rb index 5260043d43..6367d918a5 100644 --- a/test/ruby/test_lazy_enumerator.rb +++ b/test/ruby/test_lazy_enumerator.rb @@ -280,4 +280,16 @@ class TestLazyEnumerator < Test::Unit::TestCase def test_force assert_equal([1, 2, 3], (1..Float::INFINITY).lazy.take(3).force) end + + def test_inspect + assert_equal("#<Enumerator::Lazy: 1..10>", (1..10).lazy.inspect) + assert_equal('#<Enumerator::Lazy: #<Enumerator: "foo":chars>>', + "foo".chars.lazy.inspect) + assert_equal("#<Enumerator::Lazy: #<Enumerator::Lazy: 1..10>:map>", + (1..10).lazy.map {}.inspect) + l = (1..10).lazy.map {}.collect {}.flat_map {}.collect_concat {}.select {}.find_all {}.reject {}.grep(1).zip(?a..?c).take(10).take_while {}.drop(3).drop_while {}.cycle + assert_equal(<<EOS.chomp, l.inspect) +#<Enumerator::Lazy: #<Enumerator::Lazy: #<Enumerator::Lazy: #<Enumerator::Lazy: #<Enumerator::Lazy: #<Enumerator::Lazy: #<Enumerator::Lazy: #<Enumerator::Lazy: #<Enumerator::Lazy: #<Enumerator::Lazy: #<Enumerator::Lazy: #<Enumerator::Lazy: #<Enumerator::Lazy: #<Enumerator::Lazy: #<Enumerator::Lazy: 1..10>:map>:collect>:flat_map>:collect_concat>:select>:find_all>:reject>:grep>:zip>:take>:take_while>:drop>:drop_while>:cycle> +EOS + end end |