summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--enumerator.c66
-rw-r--r--spec/ruby/core/enumerator/initialize_spec.rb6
-rw-r--r--spec/ruby/core/enumerator/new_spec.rb66
-rw-r--r--test/ruby/test_enumerator.rb14
4 files changed, 69 insertions, 83 deletions
diff --git a/enumerator.c b/enumerator.c
index fe5f054c74..b4a7cb588e 100644
--- a/enumerator.c
+++ b/enumerator.c
@@ -420,15 +420,31 @@ enumerator_init(VALUE enum_obj, VALUE obj, VALUE meth, int argc, const VALUE *ar
return enum_obj;
}
+static VALUE
+convert_to_feasible_size_value(VALUE obj)
+{
+ if (NIL_P(obj)) {
+ return obj;
+ }
+ else if (rb_respond_to(obj, id_call)) {
+ return obj;
+ }
+ else if (RB_FLOAT_TYPE_P(obj) && RFLOAT_VALUE(obj) == HUGE_VAL) {
+ return obj;
+ }
+ else {
+ return rb_to_int(obj);
+ }
+}
+
/*
* call-seq:
* Enumerator.new(size = nil) { |yielder| ... }
- * Enumerator.new(obj, method = :each, *args)
*
* Creates a new Enumerator object, which can be used as an
* Enumerable.
*
- * In the first form, iteration is defined by the given block, in
+ * Iteration is defined by the given block, in
* which a "yielder" object, given as block parameter, can be used to
* yield a value by calling the +yield+ method (aliased as <code><<</code>):
*
@@ -445,52 +461,16 @@ enumerator_init(VALUE enum_obj, VALUE obj, VALUE meth, int argc, const VALUE *ar
* The optional parameter can be used to specify how to calculate the size
* in a lazy fashion (see Enumerator#size). It can either be a value or
* a callable object.
- *
- * In the deprecated second form, a generated Enumerator iterates over the
- * given object using the given method with the given arguments passed.
- *
- * Use of this form is discouraged. Use Object#enum_for or Object#to_enum
- * instead.
- *
- * e = Enumerator.new(ObjectSpace, :each_object)
- * #-> ObjectSpace.enum_for(:each_object)
- *
- * e.select { |obj| obj.is_a?(Class) } # => array of all classes
- *
*/
static VALUE
enumerator_initialize(int argc, VALUE *argv, VALUE obj)
{
- VALUE recv, meth = sym_each;
- VALUE size = Qnil;
- int kw_splat = 0;
-
- if (rb_block_given_p()) {
- rb_check_arity(argc, 0, 1);
- recv = generator_init(generator_allocate(rb_cGenerator), rb_block_proc());
- if (argc) {
- if (NIL_P(argv[0]) || rb_respond_to(argv[0], id_call) ||
- (RB_TYPE_P(argv[0], T_FLOAT) && RFLOAT_VALUE(argv[0]) == HUGE_VAL)) {
- size = argv[0];
- }
- else {
- size = rb_to_int(argv[0]);
- }
- argc = 0;
- }
- }
- else {
- rb_check_arity(argc, 1, UNLIMITED_ARGUMENTS);
- rb_warn_deprecated("Enumerator.new without a block", "Object#to_enum");
- recv = *argv++;
- if (--argc) {
- meth = *argv++;
- --argc;
- }
- kw_splat = rb_keyword_given_p();
- }
+ VALUE iter = rb_block_proc();
+ VALUE recv = generator_init(generator_allocate(rb_cGenerator), iter);
+ VALUE arg0 = rb_check_arity(argc, 0, 1) ? argv[0] : Qnil;
+ VALUE size = convert_to_feasible_size_value(arg0);
- return enumerator_init(obj, recv, meth, argc, argv, 0, size, kw_splat);
+ return enumerator_init(obj, recv, sym_each, 0, 0, 0, size, false);
}
/* :nodoc: */
diff --git a/spec/ruby/core/enumerator/initialize_spec.rb b/spec/ruby/core/enumerator/initialize_spec.rb
index 45bd650d7f..113bbf9957 100644
--- a/spec/ruby/core/enumerator/initialize_spec.rb
+++ b/spec/ruby/core/enumerator/initialize_spec.rb
@@ -11,8 +11,10 @@ describe "Enumerator#initialize" do
Enumerator.should have_private_instance_method(:initialize, false)
end
- it "returns self when given an object" do
- @uninitialized.send(:initialize, Object.new).should equal(@uninitialized)
+ ruby_version_is ''...'3.0' do
+ it "returns self when given an object" do
+ @uninitialized.send(:initialize, Object.new).should equal(@uninitialized)
+ end
end
it "returns self when given a block" do
diff --git a/spec/ruby/core/enumerator/new_spec.rb b/spec/ruby/core/enumerator/new_spec.rb
index 100edc8455..9aea9fdd17 100644
--- a/spec/ruby/core/enumerator/new_spec.rb
+++ b/spec/ruby/core/enumerator/new_spec.rb
@@ -1,42 +1,52 @@
require_relative '../../spec_helper'
describe "Enumerator.new" do
- it "creates a new custom enumerator with the given object, iterator and arguments" do
- enum = Enumerator.new(1, :upto, 3)
- enum.should be_an_instance_of(Enumerator)
- end
+ context "no block given" do
+ ruby_version_is '3.0' do
+ it "raises" do
+ -> { Enumerator.new(1, :upto, 3) }.should raise_error(ArgumentError)
+ end
+ end
- it "creates a new custom enumerator that responds to #each" do
- enum = Enumerator.new(1, :upto, 3)
- enum.respond_to?(:each).should == true
- end
+ ruby_version_is ''...'3.0' do
+ it "creates a new custom enumerator with the given object, iterator and arguments" do
+ enum = Enumerator.new(1, :upto, 3)
+ enum.should be_an_instance_of(Enumerator)
+ end
- it "creates a new custom enumerator that runs correctly" do
- Enumerator.new(1, :upto, 3).map{|x|x}.should == [1,2,3]
- end
+ it "creates a new custom enumerator that responds to #each" do
+ enum = Enumerator.new(1, :upto, 3)
+ enum.respond_to?(:each).should == true
+ end
- it "aliases the second argument to :each" do
- Enumerator.new(1..2).to_a.should == Enumerator.new(1..2, :each).to_a
- end
+ it "creates a new custom enumerator that runs correctly" do
+ Enumerator.new(1, :upto, 3).map{|x|x}.should == [1,2,3]
+ end
- it "doesn't check for the presence of the iterator method" do
- Enumerator.new(nil).should be_an_instance_of(Enumerator)
- end
+ it "aliases the second argument to :each" do
+ Enumerator.new(1..2).to_a.should == Enumerator.new(1..2, :each).to_a
+ end
- it "uses the latest define iterator method" do
- class StrangeEach
- def each
- yield :foo
+ it "doesn't check for the presence of the iterator method" do
+ Enumerator.new(nil).should be_an_instance_of(Enumerator)
end
- end
- enum = Enumerator.new(StrangeEach.new)
- enum.to_a.should == [:foo]
- class StrangeEach
- def each
- yield :bar
+
+ it "uses the latest define iterator method" do
+ class StrangeEach
+ def each
+ yield :foo
+ end
+ end
+ enum = Enumerator.new(StrangeEach.new)
+ enum.to_a.should == [:foo]
+ class StrangeEach
+ def each
+ yield :bar
+ end
+ end
+ enum.to_a.should == [:bar]
end
end
- enum.to_a.should == [:bar]
end
context "when passed a block" do
diff --git a/test/ruby/test_enumerator.rb b/test/ruby/test_enumerator.rb
index 5b634ef72f..eb15d4b616 100644
--- a/test/ruby/test_enumerator.rb
+++ b/test/ruby/test_enumerator.rb
@@ -69,22 +69,16 @@ class TestEnumerator < Test::Unit::TestCase
def test_initialize
assert_equal([1, 2, 3], @obj.to_enum(:foo, 1, 2, 3).to_a)
- begin
- deprecated_bak, Warning[:deprecated] = Warning[:deprecated], true
- _, err = capture_io do
- assert_equal([1, 2, 3], Enumerator.new(@obj, :foo, 1, 2, 3).to_a)
- end
- assert_match 'Enumerator.new without a block is deprecated', err
- ensure
- Warning[:deprecated] = deprecated_bak
- end
+ assert_raise(ArgumentError) {
+ Enumerator.new(@obj, :foo, 1, 2, 3)
+ }
assert_equal([1, 2, 3], Enumerator.new { |y| i = 0; loop { y << (i += 1) } }.take(3))
assert_raise(ArgumentError) { Enumerator.new }
enum = @obj.to_enum
assert_raise(NoMethodError) { enum.each {} }
enum.freeze
- assert_raise(FrozenError) {
+ assert_raise(ArgumentError) {
capture_io do
# warning: Enumerator.new without a block is deprecated; use Object#to_enum
enum.__send__(:initialize, @obj, :foo)