summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog14
-rw-r--r--enum.c5
-rw-r--r--enumerator.c18
-rw-r--r--internal.h3
-rw-r--r--test/ruby/test_lazy_enumerator.rb16
5 files changed, 43 insertions, 13 deletions
diff --git a/ChangeLog b/ChangeLog
index 9043918836..d1695c671a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,17 @@
+Tue Feb 5 12:48:38 2013 Marc-Andre Lafortune <ruby-core@marc-andre.ca>
+
+ * enumerator.c: Use to_enum for Enumerable methods returning
+ Enumerators.
+ This makes Lazy#cycle no longer needed, so it was removed.
+ Make Enumerator#chunk and slice_before return lazy Enumerators.
+ [Bug #7715]
+
+ * internal.h: Remove ref to rb_enum_cycle_size; no longer needed
+
+ * enum.c: Make enum_cycle_size static.
+
+ * test/ruby/test_lazy_enumerator.rb: Test for above
+
Tue Feb 5 12:48:10 2013 Marc-Andre Lafortune <ruby-core@marc-andre.ca>
* enumerator.c: Finalize and document Lazy.new. [Bug #7248]
diff --git a/enum.c b/enum.c
index db1609e06c..a07fbdb006 100644
--- a/enum.c
+++ b/enum.c
@@ -2238,9 +2238,8 @@ cycle_i(VALUE i, VALUE ary, int argc, VALUE *argv)
return Qnil;
}
-#define enum_cycle_size rb_enum_cycle_size
-VALUE
-rb_enum_cycle_size(VALUE self, VALUE args)
+static VALUE
+enum_cycle_size(VALUE self, VALUE args)
{
long mul;
VALUE n = Qnil;
diff --git a/enumerator.c b/enumerator.c
index 682e9a71cb..a8bc787874 100644
--- a/enumerator.c
+++ b/enumerator.c
@@ -463,7 +463,13 @@ lazy_to_enum_i(VALUE self, VALUE meth, int argc, VALUE *argv, VALUE (*size_fn)(A
VALUE
rb_enumeratorize_with_size(VALUE obj, VALUE meth, int argc, VALUE *argv, VALUE (*size_fn)(ANYARGS))
{
- return enumerator_init(enumerator_allocate(rb_cEnumerator), obj, meth, argc, argv, size_fn, Qnil);
+ /* Similar effect as calling obj.to_enum, i.e. dispatching to either
+ Kernel#to_enum vs Lazy#to_enum */
+ if (RTEST(rb_obj_is_kind_of(obj, rb_cLazy)))
+ return lazy_to_enum_i(obj, meth, argc, argv, size_fn);
+ else
+ return enumerator_init(enumerator_allocate(rb_cEnumerator),
+ obj, meth, argc, argv, size_fn, Qnil);
}
static VALUE
@@ -1893,12 +1899,9 @@ lazy_drop_while(VALUE obj)
}
static VALUE
-lazy_cycle(int argc, VALUE *argv, VALUE obj)
+lazy_super(int argc, VALUE *argv, VALUE lazy)
{
- if (rb_block_given_p()) {
- return rb_call_super(argc, argv);
- }
- return lazy_to_enum_i(obj, sym_cycle, argc, argv, rb_enum_cycle_size);
+ return enumerable_lazy(rb_call_super(argc, argv));
}
static VALUE
@@ -2005,8 +2008,9 @@ InitVM_Enumerator(void)
rb_define_method(rb_cLazy, "take_while", lazy_take_while, 0);
rb_define_method(rb_cLazy, "drop", lazy_drop, 1);
rb_define_method(rb_cLazy, "drop_while", lazy_drop_while, 0);
- rb_define_method(rb_cLazy, "cycle", lazy_cycle, -1);
rb_define_method(rb_cLazy, "lazy", lazy_lazy, 0);
+ rb_define_method(rb_cLazy, "chunk", lazy_super, -1);
+ rb_define_method(rb_cLazy, "slice_before", lazy_super, -1);
rb_define_alias(rb_cLazy, "force", "to_a");
diff --git a/internal.h b/internal.h
index c8317a51e8..971d6bde87 100644
--- a/internal.h
+++ b/internal.h
@@ -90,9 +90,6 @@ ID rb_id_encoding(void);
/* encoding.c */
void rb_gc_mark_encodings(void);
-/* enum.c */
-VALUE rb_enum_cycle_size(VALUE self, VALUE args);
-
/* error.c */
NORETURN(PRINTF_ARGS(void rb_compile_bug(const char*, int, const char*, ...), 3, 4));
VALUE rb_check_backtrace(VALUE);
diff --git a/test/ruby/test_lazy_enumerator.rb b/test/ruby/test_lazy_enumerator.rb
index 8e0fd50f55..c78a2d66cc 100644
--- a/test/ruby/test_lazy_enumerator.rb
+++ b/test/ruby/test_lazy_enumerator.rb
@@ -447,4 +447,20 @@ EOS
assert_raise(ArgumentError){ [].lazy.send(method) }
end
end
+
+ def test_laziness_conservation
+ bug7507 = '[ruby-core:51510]'
+ {
+ slice_before: //,
+ with_index: nil,
+ cycle: nil,
+ each_with_object: 42,
+ each_slice: 42,
+ each_entry: nil,
+ each_cons: 42,
+ }.each do |method, arg|
+ assert_equal Enumerator::Lazy, [].lazy.send(method, *arg).class, bug7507
+ end
+ assert_equal Enumerator::Lazy, [].lazy.chunk{}.class, bug7507
+ end
end