csv 3.1.9 → 3.3.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/NEWS.md +361 -0
- data/README.md +3 -6
- data/doc/csv/options/generating/write_headers.rdoc +1 -1
- data/doc/csv/options/parsing/liberal_parsing.rdoc +21 -2
- data/doc/csv/recipes/filtering.rdoc +85 -17
- data/doc/csv/recipes/generating.rdoc +2 -2
- data/doc/csv/recipes/parsing.rdoc +16 -7
- data/lib/csv/core_ext/array.rb +1 -1
- data/lib/csv/core_ext/string.rb +1 -1
- data/lib/csv/fields_converter.rb +16 -4
- data/lib/csv/input_record_separator.rb +18 -0
- data/lib/csv/parser.rb +263 -113
- data/lib/csv/row.rb +23 -1
- data/lib/csv/table.rb +18 -7
- data/lib/csv/version.rb +1 -1
- data/lib/csv/writer.rb +6 -6
- data/lib/csv.rb +535 -188
- metadata +9 -66
- data/lib/csv/delete_suffix.rb +0 -18
- data/lib/csv/match_p.rb +0 -20
data/lib/csv/row.rb
CHANGED
|
@@ -659,8 +659,30 @@ class CSV
|
|
|
659
659
|
end
|
|
660
660
|
alias_method :to_hash, :to_h
|
|
661
661
|
|
|
662
|
+
# :call-seq:
|
|
663
|
+
# row.deconstruct_keys(keys) -> hash
|
|
664
|
+
#
|
|
665
|
+
# Returns the new \Hash suitable for pattern matching containing only the
|
|
666
|
+
# keys specified as an argument.
|
|
667
|
+
def deconstruct_keys(keys)
|
|
668
|
+
if keys.nil?
|
|
669
|
+
to_h
|
|
670
|
+
else
|
|
671
|
+
keys.to_h { |key| [key, self[key]] }
|
|
672
|
+
end
|
|
673
|
+
end
|
|
674
|
+
|
|
662
675
|
alias_method :to_ary, :to_a
|
|
663
676
|
|
|
677
|
+
# :call-seq:
|
|
678
|
+
# row.deconstruct -> array
|
|
679
|
+
#
|
|
680
|
+
# Returns the new \Array suitable for pattern matching containing the values
|
|
681
|
+
# of the row.
|
|
682
|
+
def deconstruct
|
|
683
|
+
fields
|
|
684
|
+
end
|
|
685
|
+
|
|
664
686
|
# :call-seq:
|
|
665
687
|
# row.to_csv -> csv_string
|
|
666
688
|
#
|
|
@@ -681,7 +703,7 @@ class CSV
|
|
|
681
703
|
# by +index_or_header+ and +specifiers+.
|
|
682
704
|
#
|
|
683
705
|
# The nested objects may be instances of various classes.
|
|
684
|
-
# See {Dig Methods}[
|
|
706
|
+
# See {Dig Methods}[rdoc-ref:dig_methods.rdoc].
|
|
685
707
|
#
|
|
686
708
|
# Examples:
|
|
687
709
|
# source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n"
|
data/lib/csv/table.rb
CHANGED
|
@@ -890,9 +890,8 @@ class CSV
|
|
|
890
890
|
if @mode == :row or @mode == :col_or_row # by index
|
|
891
891
|
@table.delete_if(&block)
|
|
892
892
|
else # by header
|
|
893
|
-
deleted = []
|
|
894
893
|
headers.each do |header|
|
|
895
|
-
|
|
894
|
+
delete(header) if yield([header, self[header]])
|
|
896
895
|
end
|
|
897
896
|
end
|
|
898
897
|
|
|
@@ -932,7 +931,9 @@ class CSV
|
|
|
932
931
|
return enum_for(__method__) { @mode == :col ? headers.size : size } unless block_given?
|
|
933
932
|
|
|
934
933
|
if @mode == :col
|
|
935
|
-
headers.each
|
|
934
|
+
headers.each.with_index do |header, i|
|
|
935
|
+
yield([header, @table.map {|row| row[header, i]}])
|
|
936
|
+
end
|
|
936
937
|
else
|
|
937
938
|
@table.each(&block)
|
|
938
939
|
end
|
|
@@ -997,9 +998,15 @@ class CSV
|
|
|
997
998
|
# Omits the headers if option +write_headers+ is given as +false+
|
|
998
999
|
# (see {Option +write_headers+}[../CSV.html#class-CSV-label-Option+write_headers]):
|
|
999
1000
|
# table.to_csv(write_headers: false) # => "foo,0\nbar,1\nbaz,2\n"
|
|
1000
|
-
|
|
1001
|
+
#
|
|
1002
|
+
# Limit rows if option +limit+ is given like +2+:
|
|
1003
|
+
# table.to_csv(limit: 2) # => "Name,Value\nfoo,0\nbar,1\n"
|
|
1004
|
+
def to_csv(write_headers: true, limit: nil, **options)
|
|
1001
1005
|
array = write_headers ? [headers.to_csv(**options)] : []
|
|
1002
|
-
@table.
|
|
1006
|
+
limit ||= @table.size
|
|
1007
|
+
limit = @table.size + 1 + limit if limit < 0
|
|
1008
|
+
limit = 0 if limit < 0
|
|
1009
|
+
@table.first(limit).each do |row|
|
|
1003
1010
|
array.push(row.fields.to_csv(**options)) unless row.header_row?
|
|
1004
1011
|
end
|
|
1005
1012
|
|
|
@@ -1036,9 +1043,13 @@ class CSV
|
|
|
1036
1043
|
# Example:
|
|
1037
1044
|
# source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n"
|
|
1038
1045
|
# table = CSV.parse(source, headers: true)
|
|
1039
|
-
# table.inspect # => "#<CSV::Table mode:col_or_row row_count:4
|
|
1046
|
+
# table.inspect # => "#<CSV::Table mode:col_or_row row_count:4>\nName,Value\nfoo,0\nbar,1\nbaz,2\n"
|
|
1047
|
+
#
|
|
1040
1048
|
def inspect
|
|
1041
|
-
"#<#{self.class} mode:#{@mode} row_count:#{to_a.size}>"
|
|
1049
|
+
inspected = +"#<#{self.class} mode:#{@mode} row_count:#{to_a.size}>"
|
|
1050
|
+
summary = to_csv(limit: 5)
|
|
1051
|
+
inspected << "\n" << summary if summary.encoding.ascii_compatible?
|
|
1052
|
+
inspected
|
|
1042
1053
|
end
|
|
1043
1054
|
end
|
|
1044
1055
|
end
|
data/lib/csv/version.rb
CHANGED
data/lib/csv/writer.rb
CHANGED
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require_relative "
|
|
3
|
+
require_relative "input_record_separator"
|
|
4
4
|
require_relative "row"
|
|
5
5
|
|
|
6
|
-
using CSV::MatchP if CSV.const_defined?(:MatchP)
|
|
7
|
-
|
|
8
6
|
class CSV
|
|
9
7
|
# Note: Don't use this class directly. This is an internal class.
|
|
10
8
|
class Writer
|
|
@@ -41,7 +39,9 @@ class CSV
|
|
|
41
39
|
@headers ||= row if @use_headers
|
|
42
40
|
@lineno += 1
|
|
43
41
|
|
|
44
|
-
|
|
42
|
+
if @fields_converter
|
|
43
|
+
row = @fields_converter.convert(row, nil, lineno)
|
|
44
|
+
end
|
|
45
45
|
|
|
46
46
|
i = -1
|
|
47
47
|
converted_row = row.collect do |field|
|
|
@@ -96,7 +96,7 @@ class CSV
|
|
|
96
96
|
return unless @headers
|
|
97
97
|
|
|
98
98
|
converter = @options[:header_fields_converter]
|
|
99
|
-
@headers = converter.convert(@headers, nil, 0)
|
|
99
|
+
@headers = converter.convert(@headers, nil, 0, [])
|
|
100
100
|
@headers.each do |header|
|
|
101
101
|
header.freeze if header.is_a?(String)
|
|
102
102
|
end
|
|
@@ -133,7 +133,7 @@ class CSV
|
|
|
133
133
|
@column_separator = @options[:column_separator].to_s.encode(@encoding)
|
|
134
134
|
row_separator = @options[:row_separator]
|
|
135
135
|
if row_separator == :auto
|
|
136
|
-
@row_separator =
|
|
136
|
+
@row_separator = InputRecordSeparator.value.encode(@encoding)
|
|
137
137
|
else
|
|
138
138
|
@row_separator = row_separator.to_s.encode(@encoding)
|
|
139
139
|
end
|