[前][次][番号順一覧][スレッド一覧]

ruby-changes:50453

From: eregon <ko1@a...>
Date: Sun, 25 Feb 2018 22:52:19 +0900 (JST)
Subject: [ruby-changes:50453] eregon:r62575 (trunk): Add a new #filter alias for #select

eregon	2018-02-25 22:52:07 +0900 (Sun, 25 Feb 2018)

  New Revision: 62575

  https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=62575

  Log:
    Add a new #filter alias for #select
    
    * In Enumerable, Enumerator::Lazy, Array, Hash and Set
      [Feature #13784] [ruby-core:82285]
    * Share specs for the various #select#select! methods and
      reuse them for #filter/#filter!.
    * Add corresponding filter tests for select tests.
    * Update NEWS.
    
    [Fix GH-1824]
    
    From: Alexander Patrick <adp90@c...>

  Added files:
    trunk/spec/ruby/core/array/filter_spec.rb
    trunk/spec/ruby/core/array/shared/select.rb
    trunk/spec/ruby/core/enumerable/filter_spec.rb
    trunk/spec/ruby/core/hash/filter_spec.rb
    trunk/spec/ruby/core/hash/shared/select.rb
    trunk/spec/ruby/library/set/filter_spec.rb
    trunk/spec/ruby/library/set/shared/select.rb
    trunk/spec/ruby/library/set/sortedset/filter_spec.rb
    trunk/spec/ruby/library/set/sortedset/shared/select.rb
  Modified files:
    trunk/NEWS
    trunk/array.c
    trunk/enum.c
    trunk/enumerator.c
    trunk/hash.c
    trunk/lib/set.rb
    trunk/spec/ruby/core/array/select_spec.rb
    trunk/spec/ruby/core/hash/select_spec.rb
    trunk/spec/ruby/library/set/select_spec.rb
    trunk/spec/ruby/library/set/sortedset/select_spec.rb
    trunk/test/ruby/test_array.rb
    trunk/test/ruby/test_enumerator.rb
    trunk/test/ruby/test_env.rb
    trunk/test/ruby/test_hash.rb
    trunk/test/test_set.rb
Index: hash.c
===================================================================
--- hash.c	(revision 62574)
+++ hash.c	(revision 62575)
@@ -4690,6 +4690,8 @@ Init_Hash(void) https://github.com/ruby/ruby/blob/trunk/hash.c#L4690
     rb_define_method(rb_cHash, "keep_if", rb_hash_keep_if, 0);
     rb_define_method(rb_cHash, "select", rb_hash_select, 0);
     rb_define_method(rb_cHash, "select!", rb_hash_select_bang, 0);
+    rb_define_method(rb_cHash, "filter", rb_hash_select, 0);
+    rb_define_method(rb_cHash, "filter!", rb_hash_select_bang, 0);
     rb_define_method(rb_cHash, "reject", rb_hash_reject, 0);
     rb_define_method(rb_cHash, "reject!", rb_hash_reject_bang, 0);
     rb_define_method(rb_cHash, "slice", rb_hash_slice, -1);
@@ -4752,6 +4754,8 @@ Init_Hash(void) https://github.com/ruby/ruby/blob/trunk/hash.c#L4754
     rb_define_singleton_method(envtbl, "reject!", env_reject_bang, 0);
     rb_define_singleton_method(envtbl, "select", env_select, 0);
     rb_define_singleton_method(envtbl, "select!", env_select_bang, 0);
+    rb_define_singleton_method(envtbl, "filter", env_select, 0);
+    rb_define_singleton_method(envtbl, "filter!", env_select_bang, 0);
     rb_define_singleton_method(envtbl, "shift", env_shift, 0);
     rb_define_singleton_method(envtbl, "invert", env_invert, 0);
     rb_define_singleton_method(envtbl, "replace", env_replace, 1);
Index: spec/ruby/library/set/select_spec.rb
===================================================================
--- spec/ruby/library/set/select_spec.rb	(revision 62574)
+++ spec/ruby/library/set/select_spec.rb	(revision 62575)
@@ -1,42 +1,6 @@ https://github.com/ruby/ruby/blob/trunk/spec/ruby/library/set/select_spec.rb#L1
 require File.expand_path('../../../spec_helper', __FILE__)
-require 'set'
+require File.expand_path('../shared/select', __FILE__)
 
 describe "Set#select!" do
-  before :each do
-    @set = Set["one", "two", "three"]
-  end
-
-  it "yields every element of self" do
-    ret = []
-    @set.select! { |x| ret << x }
-    ret.sort.should == ["one", "two", "three"].sort
-  end
-
-  it "keeps every element from self for which the passed block returns true" do
-    @set.select! { |x| x.size != 3 }
-    @set.size.should eql(1)
-
-    @set.should_not include("one")
-    @set.should_not include("two")
-    @set.should include("three")
-  end
-
-  it "returns self when self was modified" do
-    @set.select! { false }.should equal(@set)
-  end
-
-  it "returns nil when self was not modified" do
-    @set.select! { true }.should be_nil
-  end
-
-  it "returns an Enumerator when passed no block" do
-    enum = @set.select!
-    enum.should be_an_instance_of(Enumerator)
-
-    enum.each { |x| x.size != 3 }
-
-    @set.should_not include("one")
-    @set.should_not include("two")
-    @set.should include("three")
-  end
+  it_behaves_like :set_select_bang, :select!
 end
Index: spec/ruby/library/set/shared/select.rb
===================================================================
--- spec/ruby/library/set/shared/select.rb	(nonexistent)
+++ spec/ruby/library/set/shared/select.rb	(revision 62575)
@@ -0,0 +1,42 @@ https://github.com/ruby/ruby/blob/trunk/spec/ruby/library/set/shared/select.rb#L1
+require File.expand_path('../../../../spec_helper', __FILE__)
+require 'set'
+
+describe :set_select_bang, shared: true do
+  before :each do
+    @set = Set["one", "two", "three"]
+  end
+
+  it "yields every element of self" do
+    ret = []
+    @set.send(@method) { |x| ret << x }
+    ret.sort.should == ["one", "two", "three"].sort
+  end
+
+  it "keeps every element from self for which the passed block returns true" do
+    @set.send(@method) { |x| x.size != 3 }
+    @set.size.should eql(1)
+
+    @set.should_not include("one")
+    @set.should_not include("two")
+    @set.should include("three")
+  end
+
+  it "returns self when self was modified" do
+    @set.send(@method) { false }.should equal(@set)
+  end
+
+  it "returns nil when self was not modified" do
+    @set.send(@method) { true }.should be_nil
+  end
+
+  it "returns an Enumerator when passed no block" do
+    enum = @set.send(@method)
+    enum.should be_an_instance_of(Enumerator)
+
+    enum.each { |x| x.size != 3 }
+
+    @set.should_not include("one")
+    @set.should_not include("two")
+    @set.should include("three")
+  end
+end

Property changes on: spec/ruby/library/set/shared/select.rb
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+LF
\ No newline at end of property
Index: spec/ruby/library/set/sortedset/shared/select.rb
===================================================================
--- spec/ruby/library/set/sortedset/shared/select.rb	(nonexistent)
+++ spec/ruby/library/set/sortedset/shared/select.rb	(revision 62575)
@@ -0,0 +1,35 @@ https://github.com/ruby/ruby/blob/trunk/spec/ruby/library/set/sortedset/shared/select.rb#L1
+require File.expand_path('../../../../../spec_helper', __FILE__)
+require 'set'
+
+describe :sorted_set_select_bang, shared: true do
+  before :each do
+    @set = SortedSet["one", "two", "three"]
+  end
+
+  it "yields each Object in self in sorted order" do
+    res = []
+    @set.send(@method) { |x| res << x }
+    res.should == ["one", "two", "three"].sort
+  end
+
+  it "keeps every element from self for which the passed block returns true" do
+    @set.send(@method) { |x| x.size != 3 }
+    @set.to_a.should == ["three"]
+  end
+
+  it "returns self when self was modified" do
+    @set.send(@method) { false }.should equal(@set)
+  end
+
+  it "returns nil when self was not modified" do
+    @set.send(@method) { true }.should be_nil
+  end
+
+  it "returns an Enumerator when passed no block" do
+    enum = @set.send(@method)
+    enum.should be_an_instance_of(Enumerator)
+
+    enum.each { |x| x.size != 3 }
+    @set.to_a.should == ["three"]
+  end
+end

Property changes on: spec/ruby/library/set/sortedset/shared/select.rb
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+LF
\ No newline at end of property
Index: spec/ruby/library/set/sortedset/filter_spec.rb
===================================================================
--- spec/ruby/library/set/sortedset/filter_spec.rb	(nonexistent)
+++ spec/ruby/library/set/sortedset/filter_spec.rb	(revision 62575)
@@ -0,0 +1,7 @@ https://github.com/ruby/ruby/blob/trunk/spec/ruby/library/set/sortedset/filter_spec.rb#L1
+require File.expand_path('../../../../spec_helper', __FILE__)
+require File.expand_path('../shared/select', __FILE__)
+require 'set'
+
+describe "SortedSet#filter!" do
+  it_behaves_like :sorted_set_select_bang, :filter!
+end
Index: spec/ruby/library/set/sortedset/select_spec.rb
===================================================================
--- spec/ruby/library/set/sortedset/select_spec.rb	(revision 62574)
+++ spec/ruby/library/set/sortedset/select_spec.rb	(revision 62575)
@@ -1,35 +1,7 @@ https://github.com/ruby/ruby/blob/trunk/spec/ruby/library/set/sortedset/select_spec.rb#L1
 require File.expand_path('../../../../spec_helper', __FILE__)
+require File.expand_path('../shared/select', __FILE__)
 require 'set'
 
 describe "SortedSet#select!" do
-  before :each do
-    @set = SortedSet["one", "two", "three"]
-  end
-
-  it "yields each Object in self in sorted order" do
-    res = []
-    @set.select! { |x| res << x }
-    res.should == ["one", "two", "three"].sort
-  end
-
-  it "keeps every element from self for which the passed block returns true" do
-    @set.select! { |x| x.size != 3 }
-    @set.to_a.should == ["three"]
-  end
-
-  it "returns self when self was modified" do
-    @set.select! { false }.should equal(@set)
-  end
-
-  it "returns nil when self was not modified" do
-    @set.select! { true }.should be_nil
-  end
-
-  it "returns an Enumerator when passed no block" do
-    enum = @set.select!
-    enum.should be_an_instance_of(Enumerator)
-
-    enum.each { |x| x.size != 3 }
-    @set.to_a.should == ["three"]
-  end
+  it_behaves_like :sorted_set_select_bang, :select!
 end
Index: spec/ruby/library/set/filter_spec.rb
===================================================================
--- spec/ruby/library/set/filter_spec.rb	(nonexistent)
+++ spec/ruby/library/set/filter_spec.rb	(revision 62575)
@@ -0,0 +1,6 @@ https://github.com/ruby/ruby/blob/trunk/spec/ruby/library/set/filter_spec.rb#L1
+require File.expand_path('../../../spec_helper', __FILE__)
+require File.expand_path('../shared/select', __FILE__)
+
+describe "Set#filter!" do
+  it_behaves_like :set_select_bang, :filter!
+end
Index: spec/ruby/core/array/filter_spec.rb
===================================================================
--- spec/ruby/core/array/filter_spec.rb	(nonexistent)
+++ spec/ruby/core/array/filter_spec.rb	(revision 62575)
@@ -0,0 +1,14 @@ https://github.com/ruby/ruby/blob/trunk/spec/ruby/core/array/filter_spec.rb#L1
+require File.expand_path('../../../spec_helper', __FILE__)
+require File.expand_path('../shared/select', __FILE__)
+
+describe "Array#filter" do
+  it_behaves_like :array_select, :filter
+end
+
+describe "Array#filter!" do
+  it "returns nil if no changes were made in the array" do
+    [1, 2, 3].filter! { true }.should be_nil
+  end
+
+  it_behaves_like :keep_if, :filter!
+end
Index: spec/ruby/core/array/select_spec.rb
===================================================================
--- spec/ruby/core/array/select_spec.rb	(revision 62574)
+++ spec/ruby/core/array/select_spec.rb	(revision 62575)
@@ -1,30 +1,8 @@ https://github.com/ruby/ruby/blob/trunk/spec/ruby/core/array/select_spec.rb#L1
 require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/classes', __FILE__)
-require File.expand_path('../shared/enumeratorize', __FILE__)
-require File.expand_path('../shared/keep_if', __FILE__)
-require File.expand_path('../../enumerable/shared/enumeratorized', __FILE__)
+require File.expand_path('../shared/select', __FILE__)
 
 describe "Array#select" do
-  it_behaves_like :enumeratorize, :select
-  it_behaves_like :enumeratorized_with_origin_size, :select, [1,2,3]
-
-  it "returns a new array of elements for which block is true" do
-    [1, 3, 4, 5, 6, 9].select { |i| i % ((i + 1) / 2) == 0}.should == [1, 4, 6]
-  end
-
-  it "does not return subclass instance on Array subclasses" do
-    ArraySpecs::MyArray[1, 2, 3].select { true }.should be_an_instance_of(Array)
-  end
-
-  it "properly handles recursive arrays" do
-    empty = ArraySpecs.empty_recursive_array
-    empty.select { true }.should == empty
-    empty.select { false }.should == []
-
-    array = ArraySpecs.recursive_array
-    array.select { true }.should == [1, 'two', 3.0, array, array, array, array, array]
-    array.select { false }.should == []
-  end
+  it_behaves_like :array_select, :select
 end
 
 describe "Array#select!" do
Index: spec/ruby/core/array/shared/select.rb
===================================================================
--- spec/ruby/core/array/shared/select.rb	(nonexistent)
+++ spec/ruby/core/array/shared/select.rb	(revision 62575)
@@ -0,0 +1,32 @@ https://github.com/ruby/ruby/blob/trunk/spec/ruby/core/array/shared/select.rb#L1
+require File.expand_path('../../../../spec_helper', __FILE__)
+require File.expand_path('../../fixtures/classes', __FILE__)
+require File.expand_path('../../shared/enumeratorize', __FILE__)
+require File.expand_path('../../shared/keep_if', __FILE__)
+require File.expand_path('../../../enumerable/shared/enumeratorized', __FILE__)
+
+describe :array_select, shared: true do
+  it_should_behave_like :enumeratorize
+
+  before :each do
+    @object = [1,2,3]
+  end
+  it_should_behave_like :enumeratorized_with_origin_size
+
+  it "returns a new array of elements for which block is true" do
+    [1, 3, 4, 5, 6, 9].send(@method) { |i| i % ((i + 1) / 2) == 0}.should == [1, 4, 6]
+  end
+
+  it "does not return subclass instance on Array subclasses" do
+    ArraySpecs::MyArray[1, 2, 3].send(@method) { true }.should be_an_instance_of(Array)
+  end
+
+  it "properly handles recursive arrays" do
+    empty = ArraySpecs.empty_recursive_array
+    empty.send(@method) { true }.should == empty
+    empty.send(@method) { false }.should == []
+
+    array = ArraySpecs.recursive_array
+    array.send(@method) { true }.should == [1, 'two', 3.0, array, array, array, array, array]
+    array.send(@method) { false }.should == []
+  end
+end
Index: spec/ruby/core/hash/select_spec.rb
===================================================================
--- spec/ruby/core/hash/select_spec.rb	(revision 62574)
+++ spec/ruby/core/hash/select_spec.rb	(revision 62575)
@@ -1,83 +1,10 @@ https://github.com/ruby/ruby/blob/trunk/spec/ruby/core/hash/select_spec.rb#L1
 require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/classes', __FILE__)
-require File.expand_path('../shared/iteration', __FILE__)
-require File.expand_path('../../enumerable/shared/enumeratorized', __FILE__)
+require File.expand_path('../shared/select', __FILE__)
 
 describe "Hash#select" do
-  before :each do
-    @hsh = { 1 => 2, 3 => 4, 5 => 6 }
-    @empty = {}
-  end
-
-  it "yields two arguments: key and value" do
-    all_args = []
-    { 1 => 2, 3 => 4 }.select { |*args| all_args << args }
-    all_args.sort.should == [[1, 2], [3, 4]]
-  end
-
-  it "returns a Hash of entries for which block is true" do
-    a_pairs = { 'a' => 9, 'c' => 4, 'b' => 5, 'd' => 2 }.select { |k,v| v % 2 == 0 }
-    a_pairs.should be_an_instance_of(Hash)
-    a_pairs.sort.should == [['c', 4], ['d', 2]]
-  end
-
-  it "processes entries with the same order as reject" do
-    h = { a: 9, c: 4, b: 5, d: 2 }
-
-    select_pairs = []
-    reject_pairs = []
-    h.dup.select { |*pair| select_pairs << pair }
-    h.reject { |*pair| reject_pairs << pair }
-
-    select_pairs.should == reject_pairs
-  end
-
-  it "returns an Enumerator when called on a non-empty hash without a block" do
-    @hsh.select.should be_an_instance_of(Enumerator)
-  end
-
-  it "returns an Enumerator when called on an empty hash without a block" do
-    @empty.select.should be_an_instance_of(Enumerator)
-  end
-
-  it_behaves_like :hash_iteration_no_block, :select
-  it_behaves_like :enumeratorized_with_origin_size, :select, { 1 => 2, 3 => 4, 5 => 6 }
+  it_behaves_like :hash_select, :select
 end
 
 describe "Hash#select!" do
-  before :each do
-    @hsh = { 1 => 2, 3 => 4, 5 => 6 }
-    @empty = {}
-  end
-
-  it "is equivalent to keep_if if changes are made" do
-    h = { a: 2 }
-    h.select! { |k,v| v <= 1 }.should equal h
-
-    h = { 1 => 2, 3 => 4 }
-    all_args_select = []
-    h.dup.select! { |*args| all_args_select << args }
-    all_args_select.should == [[1, 2], [3, 4]]
-  end
-
-  it "removes all entries if the block is false" do
-    h = { a: 1, b: 2, c: 3 }
-    h.select! { |k,v| false }.should equal(h)
-    h.should == {}
-  end
-
-  it "returns nil if no changes were made" do
-    { a: 1 }.select! { |k,v| v <= 1 }.should == nil
-  end
-
-  it "raises a #{frozen_error_class} if called on an empty frozen instance" do
-    lambda { HashSpecs.empty_frozen_hash.select! { false } }.should raise_error(frozen_error_class)
-  end
-
-  it "raises a #{frozen_error_class} if called on a frozen instance that would not be modified" do
-    lambda { HashSpecs.frozen_hash.select! { true } }.should raise_error(frozen_error_class)
-  end
-
-  it_behaves_like :hash_iteration_no_block, :select!
-  it_behaves_like :enumeratorized_with_origin_size, :select!, { 1 => 2, 3 => 4, 5 => 6 }
+  it_behaves_like :hash_select!, :select!
 end
Index: spec/ruby/core/hash/shared/select.rb
===================================================================
--- spec/ruby/core/hash/shared/select.rb	(nonexistent)
+++ spec/ruby/core/hash/shared/select.rb	(revision 62575)
@@ -0,0 +1,91 @@ https://github.com/ruby/ruby/blob/trunk/spec/ruby/core/hash/shared/select.rb#L1
+require File.expand_path('../../../../spec_helper', __FILE__)
+require File.expand_path('../../fixtures/classes', __FILE__)
+require File.expand_path('../../shared/iteration', __FILE__)
+require File.expand_path('../../../enumerable/shared/enumeratorized', __FILE__)
+
+describe :hash_select, shared: true do
+  before :each do
+    @hsh = { 1 => 2, 3 => 4, 5 => 6 }
+    @empty = {}
+  end
+
+  it "yields two arguments: key and value" do
+    all_args = []
+    { 1 => 2, 3 => 4 }.send(@method) { |*args| all_args << args }
+    all_args.sort.should == [[1, 2], [3, 4]]
+  end
+
+  it "returns a Hash of entries for which block is true" do
+    a_pairs = { 'a' => 9, 'c' => 4, 'b' => 5, 'd' => 2 }.send(@method) { |k,v| v % 2 == 0 }
+    a_pairs.should be_an_instance_of(Hash)
+    a_pairs.sort.should == [['c', 4], ['d', 2]]
+  end
+
+  it "processes entries with the same order as reject" do
+    h = { a: 9, c: 4, b: 5, d: 2 }
+
+    select_pairs = []
+    reject_pairs = []
+    h.dup.send(@method) { |*pair| select_pairs << pair }
+    h.reject { |*pair| reject_pairs << pair }
+
+    select_pairs.should == reject_pairs
+  end
+
+  it "returns an Enumerator when called on a non-empty hash without a block" do
+    @hsh.send(@method).should be_an_instance_of(Enumerator)
+  end
+
+  it "returns an Enumerator when called on an empty hash without a block" do
+    @empty.send(@method).should be_an_instance_of(Enumerator)
+  end
+
+  it_should_behave_like :hash_iteration_no_block
+
+  before :each do
+    @object = { 1 => 2, 3 => 4, 5 => 6 }
+  end
+  it_should_behave_like :enumeratorized_with_origin_size
+end
+
+describe :hash_select!, shared: true do
+  before :each do
+    @hsh = { 1 => 2, 3 => 4, 5 => 6 }
+    @empty = {}
+  end
+
+  it "is equivalent to keep_if if changes are made" do
+    h = { a: 2 }
+    h.send(@method) { |k,v| v <= 1 }.should equal h
+
+    h = { 1 => 2, 3 => 4 }
+    all_args_select = []
+    h.dup.send(@method) { |*args| all_args_select << args }
+    all_args_select.should == [[1, 2], [3, 4]]
+  end
+
+  it "removes all entries if the block is false" do
+    h = { a: 1, b: 2, c: 3 }
+    h.send(@method) { |k,v| false }.should equal(h)
+    h.should == {}
+  end
+
+  it "returns nil if no changes were made" do
+    { a: 1 }.send(@method) { |k,v| v <= 1 }.should == nil
+  end
+
+  it "raises a #{frozen_error_class} if called on an empty frozen instance" do
+    lambda { HashSpecs.empty_frozen_hash.send(@method) { false } }.should raise_error(frozen_error_class)
+  end
+
+  it "raises a #{frozen_error_class} if called on a frozen instance that would not be modified" do
+    lambda { HashSpecs.frozen_hash.send(@method) { true } }.should raise_error(frozen_error_class)
+  end
+
+  it_should_behave_like :hash_iteration_no_block
+
+  before :each do
+    @object = { 1 => 2, 3 => 4, 5 => 6 }
+  end
+  it_should_behave_like :enumeratorized_with_origin_size
+end
Index: spec/ruby/core/hash/filter_spec.rb
===================================================================
--- spec/ruby/core/hash/filter_spec.rb	(nonexistent)
+++ spec/ruby/core/hash/filter_spec.rb	(revision 62575)
@@ -0,0 +1,10 @@ https://github.com/ruby/ruby/blob/trunk/spec/ruby/core/hash/filter_spec.rb#L1
+require File.expand_path('../../../spec_helper', __FILE__)
+require File.expand_path('../shared/select', __FILE__)
+
+describe "Hash#filter" do
+  it_behaves_like :hash_select, :filter
+end
+
+describe "Hash#filter!" do
+  it_behaves_like :hash_select!, :filter!
+end
Index: spec/ruby/core/enumerable/filter_spec.rb
===================================================================
--- spec/ruby/core/enumerable/filter_spec.rb	(nonexistent)
+++ spec/ruby/core/enumerable/filter_spec.rb	(revision 62575)
@@ -0,0 +1,7 @@ https://github.com/ruby/ruby/blob/trunk/spec/ruby/core/enumerable/filter_spec.rb#L1
+require File.expand_path('../../../spec_helper', __FILE__)
+require File.expand_path('../fixtures/classes', __FILE__)
+require File.expand_path('../shared/find_all', __FILE__)
+
+describe "Enumerable#filter (... truncated)

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]