summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorktsj <ktsj@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2016-09-07 06:06:09 +0000
committerktsj <ktsj@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2016-09-07 06:06:09 +0000
commitb425d4f19ad9efaefcb1a767a6ea26e6d40e3985 (patch)
tree203abbebd3964eb0c682b1ba0a7ab88ee04a6f08
parentf60caf13f9d2a54a7879c80b2df4829800798608 (diff)
* lib/csv.rb (CSV::{Row,Table}#{each,delete_if}): returns an enumerator
if no block is given. [ruby-core:75346] [Feature #11058] * test/csv/test_row.rb: add test for above. * test/csv/test_table.rb: ditto. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@56083 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r--ChangeLog9
-rw-r--r--lib/csv.rb20
-rwxr-xr-xtest/csv/test_row.rb25
-rwxr-xr-xtest/csv/test_table.rb59
4 files changed, 108 insertions, 5 deletions
diff --git a/ChangeLog b/ChangeLog
index cc1cacd9ac1..32e3521c130 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+Wed Sep 7 14:56:59 2016 Kazuki Tsujimoto <kazuki@callcc.net>
+
+ * lib/csv.rb (CSV::{Row,Table}#{each,delete_if}): returns an enumerator
+ if no block is given. [ruby-core:75346] [Feature #11058]
+
+ * test/csv/test_row.rb: add test for above.
+
+ * test/csv/test_table.rb: ditto.
+
Wed Sep 7 14:50:01 2016 Kazuki Tsujimoto <kazuki@callcc.net>
* gems/bundled_gems: update to power_assert 0.3.1.
diff --git a/lib/csv.rb b/lib/csv.rb
index b68bcb0fc53..03b87983e69 100644
--- a/lib/csv.rb
+++ b/lib/csv.rb
@@ -431,7 +431,11 @@ class CSV
#
# This method returns the row for chaining.
#
+ # If no block is given, an Enumerator is returned.
+ #
def delete_if(&block)
+ block or return enum_for(__method__) { size }
+
@row.delete_if(&block)
self # for chaining
@@ -500,13 +504,15 @@ class CSV
#
# Yields each pair of the row as header and field tuples (much like
- # iterating over a Hash).
+ # iterating over a Hash). This method returns the row for chaining.
#
- # Support for Enumerable.
+ # If no block is given, an Enumerator is returned.
#
- # This method returns the row for chaining.
+ # Support for Enumerable.
#
def each(&block)
+ block or return enum_for(__method__) { size }
+
@row.each(&block)
self # for chaining
@@ -822,7 +828,11 @@ class CSV
#
# This method returns the table for chaining.
#
+ # If no block is given, an Enumerator is returned.
+ #
def delete_if(&block)
+ block or return enum_for(__method__) { @mode == :row or @mode == :col_or_row ? size : headers.size }
+
if @mode == :row or @mode == :col_or_row # by index
@table.delete_if(&block)
else # by header
@@ -845,7 +855,11 @@ class CSV
#
# This method returns the table for chaining.
#
+ # If no block is given, an Enumerator is returned.
+ #
def each(&block)
+ block or return enum_for(__method__) { @mode == :col ? headers.size : size }
+
if @mode == :col
headers.each { |header| block[[header, self[header]]] }
else
diff --git a/test/csv/test_row.rb b/test/csv/test_row.rb
index 1fa15d392ad..1cb851b027e 100755
--- a/test/csv/test_row.rb
+++ b/test/csv/test_row.rb
@@ -209,9 +209,20 @@ class TestCSV::Row < TestCSV
# by header
assert_equal(["C", 3], @row.delete("C"))
- # using a block
+ end
+
+ def test_delete_if
assert_equal(@row, @row.delete_if { |h, f| h == "A" and not f.nil? })
- assert_equal([["A", nil]], @row.to_a)
+ assert_equal([["B", 2], ["C", 3], ["A", nil]], @row.to_a)
+ end
+
+ def test_delete_if_without_block
+ enum = @row.delete_if
+ assert_instance_of(Enumerator, enum)
+ assert_equal(@row.size, enum.size)
+
+ assert_equal(@row, enum.each { |h, f| h == "A" and not f.nil? })
+ assert_equal([["B", 2], ["C", 3], ["A", nil]], @row.to_a)
end
def test_fields
@@ -281,6 +292,16 @@ class TestCSV::Row < TestCSV
# verify that we can chain the call
assert_equal(@row, @row.each { })
+
+ # without block
+ ary = @row.to_a
+ enum = @row.each
+ assert_instance_of(Enumerator, enum)
+ assert_equal(@row.size, enum.size)
+ enum.each do |pair|
+ assert_equal(ary.first.first, pair.first)
+ assert_equal(ary.shift.last, pair.last)
+ end
end
def test_enumerable
diff --git a/test/csv/test_table.rb b/test/csv/test_table.rb
index 80e553e83f3..25ef11a772a 100755
--- a/test/csv/test_table.rb
+++ b/test/csv/test_table.rb
@@ -220,6 +220,17 @@ class TestCSV::Table < TestCSV
# verify that we can chain the call
assert_equal(@table, @table.each { })
+ # without block
+ enum = @table.each
+ assert_instance_of(Enumerator, enum)
+ assert_equal(@table.size, enum.size)
+
+ i = 0
+ enum.each do |row|
+ assert_equal(@rows[i], row)
+ i += 1
+ end
+
###################
### Column Mode ###
###################
@@ -231,6 +242,17 @@ class TestCSV::Table < TestCSV
assert_equal(@table[header], column)
end
+ # without block
+ enum = @table.each
+ assert_instance_of(Enumerator, enum)
+ assert_equal(@table.headers.size, enum.size)
+
+ headers = @table.headers
+ enum.each do |header, column|
+ assert_equal(headers.shift, header)
+ assert_equal(@table[header], column)
+ end
+
############################
### One Shot Mode Change ###
############################
@@ -363,6 +385,24 @@ class TestCSV::Table < TestCSV
END_RESULT
end
+ def test_delete_if_row_without_block
+ ######################
+ ### Mixed/Row Mode ###
+ ######################
+ enum = @table.delete_if
+ assert_instance_of(Enumerator, enum)
+ assert_equal(@table.size, enum.size)
+
+ # verify that we can chain the call
+ assert_equal(@table, enum.each { |row| (row["B"] % 2).zero? })
+
+ # verify resulting table
+ assert_equal(<<-END_RESULT.gsub(/^\s+/, ""), @table.to_csv)
+ A,B,C
+ 4,5,6
+ END_RESULT
+ end
+
def test_delete_if_column
###################
### Column Mode ###
@@ -378,6 +418,25 @@ class TestCSV::Table < TestCSV
END_RESULT
end
+ def test_delete_if_column_without_block
+ ###################
+ ### Column Mode ###
+ ###################
+ @table.by_col!
+
+ enum = @table.delete_if
+ assert_instance_of(Enumerator, enum)
+ assert_equal(@table.headers.size, enum.size)
+
+ assert_equal(@table, enum.each { |h, v| h > "A" })
+ assert_equal(<<-END_RESULT.gsub(/^\s+/, ""), @table.to_csv)
+ A
+ 1
+ 4
+ 7
+ END_RESULT
+ end
+
def test_values_at
##################
### Mixed Mode ###