csv 3.1.4 → 3.1.5

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: dad2154faebc0d08b471d1f5624752997374f8472dc2408756d7a78efb87d9c9
4
- data.tar.gz: 9c6e071bcf07ab25aa0ff068030b42dbb47968d9f9e7aa5b04a1ff33ed12c2ea
3
+ metadata.gz: eec352a246dc1189213c78e35541e9903f172889792b92a23d6b8d7215d9ae37
4
+ data.tar.gz: 63754025784b9d6d26686b48efe8627b18c1aaa26e14f1261d14a09a4921612e
5
5
  SHA512:
6
- metadata.gz: 4da5b31e15b5c215d1f346c330a3d86ebea640cc4af4c33bd0aa238ac4b9b5cde2c72fc7edcd045de60f4cacb49a5ed8cbbf8a963a1a0750d16f5472faa95c1c
7
- data.tar.gz: 83ee56fae5acb6afdb8d722e0c0182f17112a157a2ab6ad0b30a60d524fd146850a1afe360217c2e2b5af36335668716289612ae1817d98c77b2ea2c5d610240
6
+ metadata.gz: c1b9895d4735d3f7a1376765d8e71a03388d4b8f52ace5a8eab3126e1f3167f77fcfd312212fdbdbda496d4a2f837a966bf33b871bee96f633c536b566ce0a9f
7
+ data.tar.gz: 9347baa988315b544d41ec23ded72a812dec09b7c0832c72bc4ff3be950e25d0f2184f9ed43967113ddb63e56e29c847bffb469b7883ad4207b913368057b58c
data/NEWS.md CHANGED
@@ -1,5 +1,23 @@
1
1
  # News
2
2
 
3
+ ## 3.1.5 - 2020-05-18
4
+
5
+ ### Improvements
6
+
7
+ * Improved document.
8
+ [GitHub#124][Patch by Burdette Lamar]
9
+
10
+ ### Fixes
11
+
12
+ * Added missing document files.
13
+ [GitHub#125][Reported by joast]
14
+
15
+ ### Thanks
16
+
17
+ * Burdette Lamar
18
+
19
+ * joast
20
+
3
21
  ## 3.1.4 - 2020-05-17
4
22
 
5
23
  ### Improvements
@@ -0,0 +1,45 @@
1
+ ====== Option +col_sep+
2
+
3
+ Specifies the \String field separator to be used
4
+ for both parsing and generating.
5
+ The \String will be transcoded into the data's \Encoding before use.
6
+
7
+ Default value:
8
+ CSV::DEFAULT_OPTIONS.fetch(:col_sep) # => "," (comma)
9
+
10
+ For examples in this section:
11
+ ary = ['a', 'b', 'c']
12
+
13
+ Using the default:
14
+ str = CSV.generate_line(line)
15
+ str # => "a,b,c\n"
16
+ ary = CSV.parse_line(str)
17
+ ary # => ["a", "b", "c"]
18
+
19
+ Using +:+ (colon):
20
+ col_sep = ':'
21
+ str = CSV.generate_line(ary, col_sep: col_sep)
22
+ str # => "a:b:c\n"
23
+ ary = CSV.parse_line(str, col_sep: col_sep)
24
+ ary # => [["a", "b", "c"]]
25
+
26
+ Using +::+ (two colons):
27
+ col_sep = '::'
28
+ str = CSV.generate_line(ary, col_sep: col_sep)
29
+ str # => "a::b::c\n"
30
+ ary = CSV.parse_line(str, col_sep: col_sep)
31
+ ary # => [["a", "b", "c"]]
32
+
33
+ ---
34
+
35
+ Raises an exception if given the empty \String:
36
+ col_sep = ''
37
+ # Raises ArgumentError (:col_sep must be 1 or more characters: "")
38
+ CSV.parse_line("a:b:c\n", col_sep: col_sep)
39
+
40
+ Raises an exception if the given value is not String-convertible:
41
+ col_sep = BasicObject.new
42
+ # Raises NoMethodError (undefined method `to_s' for #<BasicObject:>)
43
+ CSV.generate_line(line, col_sep: col_sep)
44
+ # Raises NoMethodError (undefined method `to_s' for #<BasicObject:>)
45
+ CSV.parse(str, col_sep: col_sep)
@@ -0,0 +1,45 @@
1
+ ====== Option +converters+
2
+
3
+ Specifies a single field converter name or \Proc,
4
+ or an \Array of field converter names and Procs.
5
+
6
+ See {Field Converters}[#class-CSV-label-Field+Converters]
7
+
8
+ Default value:
9
+ CSV::DEFAULT_OPTIONS.fetch(:converters) # => nil
10
+
11
+ The value may be a single field converter name:
12
+ str = '1,2,3'
13
+ # Without a converter
14
+ ary = CSV.parse_line(str)
15
+ ary # => ["1", "2", "3"]
16
+ # With built-in converter :integer
17
+ ary = CSV.parse_line(str, converters: :integer)
18
+ ary # => [1, 2, 3]
19
+
20
+ The value may be an \Array of field converter names:
21
+ str = '1,3.14159'
22
+ # Without converters
23
+ ary = CSV.parse_line(str)
24
+ ary # => ["1", "3.14159"]
25
+ # With built-in converters
26
+ ary = CSV.parse_line(str, converters: [:integer, :float])
27
+ ary # => [1, 3.14159]
28
+
29
+ The value may be a \Proc custom converter:
30
+ str = ' foo , bar , baz '
31
+ # Without a converter
32
+ ary = CSV.parse_line(str)
33
+ ary # => [" foo ", " bar ", " baz "]
34
+ # With a custom converter
35
+ ary = CSV.parse_line(str, converters: proc {|field| field.strip })
36
+ ary # => ["foo", "bar", "baz"]
37
+
38
+ See also {Custom Converters}[#class-CSV-label-Custom+Converters]
39
+
40
+ ---
41
+
42
+ Raises an exception if the converter is not a converter name or a \Proc:
43
+ str = 'foo,0'
44
+ # Raises NoMethodError (undefined method `arity' for nil:NilClass)
45
+ CSV.parse(str, converters: :foo)
@@ -0,0 +1,13 @@
1
+ ====== Option +empty_value+
2
+
3
+ Specifies the object that is to be substituted
4
+ for each field that has an empty \String.
5
+
6
+ Default value:
7
+ CSV::DEFAULT_OPTIONS.fetch(:empty_value) # => "" (empty string)
8
+
9
+ With the default, <tt>""</tt>:
10
+ CSV.parse_line('a,"",b,"",c') # => ["a", "", "b", "", "c"]
11
+
12
+ With a different object:
13
+ CSV.parse_line('a,"",b,"",c', empty_value: 'x') # => ["a", "x", "b", "x", "c"]
@@ -0,0 +1,39 @@
1
+ ====== Option +field_size_limit+
2
+
3
+ Specifies the \Integer field size limit.
4
+
5
+ Default value:
6
+ CSV::DEFAULT_OPTIONS.fetch(:field_size_limit) # => nil
7
+
8
+ This is a maximum size CSV will read ahead looking for the closing quote for a field.
9
+ (In truth, it reads to the first line ending beyond this size.)
10
+ If a quote cannot be found within the limit CSV will raise a MalformedCSVError,
11
+ assuming the data is faulty.
12
+ You can use this limit to prevent what are effectively DoS attacks on the parser.
13
+ However, this limit can cause a legitimate parse to fail;
14
+ therefore the default value is +nil+ (no limit).
15
+
16
+ For the examples in this section:
17
+ str = <<~EOT
18
+ "a","b"
19
+ "
20
+ 2345
21
+ ",""
22
+ EOT
23
+ str # => "\"a\",\"b\"\n\"\n2345\n\",\"\"\n"
24
+
25
+ Using the default +nil+:
26
+ ary = CSV.parse(str)
27
+ ary # => [["a", "b"], ["\n2345\n", ""]]
28
+
29
+ Using <tt>50</tt>:
30
+ field_size_limit = 50
31
+ ary = CSV.parse(str, field_size_limit: field_size_limit)
32
+ ary # => [["a", "b"], ["\n2345\n", ""]]
33
+
34
+ ---
35
+
36
+ Raises an exception if a field is too long:
37
+ big_str = "123456789\n" * 1024
38
+ # Raises CSV::MalformedCSVError (Field size exceeded in line 1.)
39
+ CSV.parse('valid,fields,"' + big_str + '"', field_size_limit: 2048)
@@ -0,0 +1,17 @@
1
+ ====== Option +force_quotes+
2
+
3
+ Specifies the boolean that determines whether each output field is to be double-quoted.
4
+
5
+ Default value:
6
+ CSV::DEFAULT_OPTIONS.fetch(:force_quotes) # => false
7
+
8
+ For examples in this section:
9
+ ary = ['foo', 0, nil]
10
+
11
+ Using the default, +false+:
12
+ str = CSV.generate_line(ary)
13
+ str # => "foo,0,\n"
14
+
15
+ Using +true+:
16
+ str = CSV.generate_line(ary, force_quotes: true)
17
+ str # => "\"foo\",\"0\",\"\"\n"
@@ -0,0 +1,31 @@
1
+ ====== Option +header_converters+
2
+
3
+ Specifies a \String converter name or an \Array of converter names.
4
+
5
+ Default value:
6
+ CSV::DEFAULT_OPTIONS.fetch(:header_converters) # => nil
7
+
8
+ Identical in functionality to option {converters}[#class-CSV-label-Option+converters]
9
+ except that:
10
+ - The converters apply only to the header row.
11
+ - The built-in header converters are +:downcase+ and +:symbol+.
12
+
13
+ Examples:
14
+ str = <<-EOT
15
+ foo,0
16
+ bar,1
17
+ baz,2
18
+ EOT
19
+ headers = ['Name', 'Value']
20
+ # With no header converter
21
+ csv = CSV.parse(str, headers: headers)
22
+ csv.headers # => ["Name", "Value"]
23
+ # With header converter :downcase
24
+ csv = CSV.parse(str, headers: headers, header_converters: :downcase)
25
+ csv.headers # => ["name", "value"]
26
+ # With header converter :symbol
27
+ csv = CSV.parse(str, headers: headers, header_converters: :symbol)
28
+ csv.headers # => [:name, :value]
29
+ # With both
30
+ csv = CSV.parse(str, headers: headers, header_converters: [:downcase, :symbol])
31
+ csv.headers # => [:name, :value]
@@ -0,0 +1,63 @@
1
+ ====== Option +headers+
2
+
3
+ Specifies a boolean, \Symbol, \Array, or \String to be used
4
+ to define column headers.
5
+
6
+ Default value:
7
+ CSV::DEFAULT_OPTIONS.fetch(:headers) # => false
8
+
9
+ ---
10
+
11
+ Without +headers+:
12
+ str = <<-EOT
13
+ Name,Count
14
+ foo,0
15
+ bar,1
16
+ bax,2
17
+ EOT
18
+ csv = CSV.new(str)
19
+ csv # => #<CSV io_type:StringIO encoding:UTF-8 lineno:0 col_sep:"," row_sep:"\n" quote_char:"\"">
20
+ csv.headers # => nil
21
+ csv.shift # => ["Name", "Count"]
22
+
23
+ ---
24
+
25
+ If set to +true+ or the \Symbol +:first_row+,
26
+ the first row of the data is treated as a row of headers:
27
+ str = <<-EOT
28
+ Name,Count
29
+ foo,0
30
+ bar,1
31
+ bax,2
32
+ EOT
33
+ csv = CSV.new(str, headers: true)
34
+ csv # => #<CSV io_type:StringIO encoding:UTF-8 lineno:2 col_sep:"," row_sep:"\n" quote_char:"\"" headers:["Name", "Count"]>
35
+ csv.headers # => ["Name", "Count"]
36
+ csv.shift # => #<CSV::Row "Name":"bar" "Count":"1">
37
+
38
+ ---
39
+
40
+ If set to an \Array, the \Array elements are treated as headers:
41
+ str = <<-EOT
42
+ foo,0
43
+ bar,1
44
+ bax,2
45
+ EOT
46
+ csv = CSV.new(str, headers: ['Name', 'Count'])
47
+ csv
48
+ csv.headers # => ["Name", "Count"]
49
+ csv.shift # => #<CSV::Row "Name":"bar" "Count":"1">
50
+
51
+ ---
52
+
53
+ If set to a \String +str+, method <tt>CSV::parse_line(str, options)</tt> is called
54
+ with the current +options+, and the returned \Array is treated as headers:
55
+ str = <<-EOT
56
+ foo,0
57
+ bar,1
58
+ bax,2
59
+ EOT
60
+ csv = CSV.new(str, headers: 'Name,Count')
61
+ csv
62
+ csv.headers # => ["Name", "Count"]
63
+ csv.shift # => #<CSV::Row "Name":"bar" "Count":"1">
@@ -0,0 +1,19 @@
1
+ ====== Option +liberal_parsing+
2
+
3
+ Specifies the boolean value that determines whether
4
+ CSV will attempt to parse input not conformant with RFC 4180,
5
+ such as double quotes in unquoted fields.
6
+
7
+ Default value:
8
+ CSV::DEFAULT_OPTIONS.fetch(:liberal_parsing) # => false
9
+
10
+ For examples in this section:
11
+ str = 'is,this "three, or four",fields'
12
+
13
+ Without +liberal_parsing+:
14
+ # Raises CSV::MalformedCSVError (Illegal quoting in str 1.)
15
+ CSV.parse_line(str)
16
+
17
+ With +liberal_parsing+:
18
+ ary = CSV.parse_line(str, liberal_parsing: true)
19
+ ary # => ["is", "this \"three", " or four\"", "fields"]
@@ -0,0 +1,12 @@
1
+ ====== Option +nil_value+
2
+
3
+ Specifies the object that is to be substituted for each null (no-text) field.
4
+
5
+ Default value:
6
+ CSV::DEFAULT_OPTIONS.fetch(:nil_value) # => nil
7
+
8
+ With the default, +nil+:
9
+ CSV.parse_line('a,,b,,c') # => ["a", nil, "b", nil, "c"]
10
+
11
+ With a different object:
12
+ CSV.parse_line('a,,b,,c', nil_value: 0) # => ["a", 0, "b", 0, "c"]
@@ -0,0 +1,32 @@
1
+ ====== Option +quote_char+
2
+
3
+ Specifies the character (\String of length 1) used used to quote fields
4
+ in both parsing and generating.
5
+ This String will be transcoded into the data's \Encoding before use.
6
+
7
+ Default value:
8
+ CSV::DEFAULT_OPTIONS.fetch(:quote_char) # => "\"" (backslash)
9
+
10
+ This is useful for an application that incorrectly uses <tt>'</tt> (single-quote)
11
+ to quote fields, instead of the correct <tt>"</tt> (double-quote).
12
+
13
+ Using the default:
14
+ ary = ['a', 'b', '"c"', 'd']
15
+ str = CSV.generate_line(ary)
16
+ str # => "a,b,\"\"\"c\"\"\",d\n"
17
+ ary = CSV.parse_line(str)
18
+ ary # => ["a", "b", "\"c\"", "d"]
19
+
20
+ Using <tt>'</tt> (single-quote):
21
+ quote_char = "'"
22
+ ary = ['a', 'b', '\'c\'', 'd']
23
+ str = CSV.generate_line(ary, quote_char: quote_char)
24
+ str # => "a,b,'''c''',d\n"
25
+ ary = CSV.parse_line(str, quote_char: quote_char)
26
+ ary # => [["a", "b", "'c'", "d"]]
27
+
28
+ ---
29
+
30
+ Raises an exception if the \String length is greater than 1:
31
+ # Raises ArgumentError (:quote_char has to be nil or a single character String)
32
+ CSV.new('', quote_char: 'xx')
@@ -0,0 +1,12 @@
1
+ ====== Option +quote_empty+
2
+
3
+ Specifies the boolean that determines whether an empty value is to be double-quoted.
4
+
5
+ Default value:
6
+ CSV::DEFAULT_OPTIONS.fetch(:quote_empty) # => true
7
+
8
+ With the default +true+:
9
+ CSV.generate_line(['"', ""]) # => "\"\"\"\",\"\"\n"
10
+
11
+ With +false+:
12
+ CSV.generate_line(['"', ""], quote_empty: false) # => "\"\"\"\",\n"
@@ -0,0 +1,22 @@
1
+ ====== Option +return_headers+
2
+
3
+ Specifies the boolean that determines whether method #shift
4
+ returns or ignores the header row.
5
+
6
+ Default value:
7
+ CSV::DEFAULT_OPTIONS.fetch(:return_headers) # => false
8
+
9
+ Examples:
10
+ str = <<-EOT
11
+ Name,Count
12
+ foo,0
13
+ bar,1
14
+ bax,2
15
+ EOT
16
+ # Without return_headers first row is str.
17
+ csv = CSV.new(str, headers: true)
18
+ csv.shift # => #<CSV::Row "Name":"foo" "Count":"0">
19
+ # With return_headers first row is headers.
20
+ csv = CSV.new(str, headers: true, return_headers: true)
21
+ csv.shift # => #<CSV::Row "Name":"Name" "Count":"Count">
22
+
@@ -0,0 +1,91 @@
1
+ ====== Option +row_sep+
2
+
3
+ Specifies the row separator, a \String or the \Symbol <tt>:auto</tt> (see below),
4
+ to be used for both parsing and generating.
5
+
6
+ Default value:
7
+ CSV::DEFAULT_OPTIONS.fetch(:row_sep) # => :auto
8
+
9
+ ---
10
+
11
+ When +row_sep+ is a \String, that \String becomes the row separator.
12
+ The String will be transcoded into the data's Encoding before use.
13
+
14
+ Using <tt>"\n"</tt>:
15
+ str = CSV.generate do |csv|
16
+ csv << [:foo, 0]
17
+ csv << [:bar, 1]
18
+ csv << [:baz, 2]
19
+ end
20
+ str # => "foo,0\nbar,1\nbaz,2\n"
21
+ ary = CSV.parse(str)
22
+ ary # => [["foo", "0"], ["bar", "1"], ["baz", "2"]]
23
+
24
+ Using <tt>|</tt> (pipe):
25
+ row_sep = '|'
26
+ str = CSV.generate(row_sep: row_sep) do |csv|
27
+ csv << [:foo, 0]
28
+ csv << [:bar, 1]
29
+ csv << [:baz, 2]
30
+ end
31
+ str # => "foo,0|bar,1|baz,2|"
32
+ ary = CSV.parse(str, row_sep: row_sep)
33
+ ary # => [["foo", "0"], ["bar", "1"], ["baz", "2"]]
34
+
35
+ Using <tt>--</tt> (two hyphens):
36
+ row_sep = '--'
37
+ str = CSV.generate(row_sep: row_sep) do |csv|
38
+ csv << [:foo, 0]
39
+ csv << [:bar, 1]
40
+ csv << [:baz, 2]
41
+ end
42
+ str # => "foo,0--bar,1--baz,2--"
43
+ ary = CSV.parse(str, row_sep: row_sep)
44
+ ary # => [["foo", "0"], ["bar", "1"], ["baz", "2"]]
45
+
46
+ Using <tt>''</tt> (empty string):
47
+ row_sep = ''
48
+ str = CSV.generate(row_sep: row_sep) do |csv|
49
+ csv << [:foo, 0]
50
+ csv << [:bar, 1]
51
+ csv << [:baz, 2]
52
+ end
53
+ str # => "foo,0bar,1baz,2"
54
+ ary = CSV.parse(str, row_sep: row_sep)
55
+ ary # => [["foo", "0bar", "1baz", "2"]]
56
+
57
+ ---
58
+
59
+ When +row_sep+ is the \Symbol +:auto+ (the default),
60
+ invokes auto-discovery of the row separator.
61
+
62
+ Auto-discovery reads ahead in the data looking for the next <tt>\r\n</tt>, +\n+, or +\r+ sequence.
63
+ The sequence will be selected even if it occurs in a quoted field,
64
+ assuming that you would have the same line endings there.
65
+
66
+ row_sep = :auto
67
+ str = CSV.generate(row_sep: row_sep) do |csv|
68
+ csv << [:foo, 0]
69
+ csv << [:bar, 1]
70
+ csv << [:baz, 2]
71
+ end
72
+ str # => "foo,0\nbar,1\nbaz,2\n"
73
+ ary = CSV.parse(str, row_sep: row_sep)
74
+ ary # => [["foo", "0"], ["bar", "1"], ["baz", "2"]]
75
+
76
+ The default <tt>$INPUT_RECORD_SEPARATOR</tt> (<tt>$/</tt>) is used
77
+ if any of the following is true:
78
+ * None of those sequences is found.
79
+ * Data is +ARGF+, +STDIN+, +STDOUT+, or +STDERR+.
80
+ * The stream is only available for output.
81
+
82
+ Obviously, discovery takes a little time. Set manually if speed is important. Also note that IO objects should be opened in binary mode on Windows if this feature will be used as the line-ending translation can cause problems with resetting the document position to where it was before the read ahead.
83
+
84
+ ---
85
+
86
+ Raises an exception if the given value is not String-convertible:
87
+ row_sep = BasicObject.new
88
+ # Raises NoMethodError (undefined method `to_s' for #<BasicObject:>)
89
+ CSV.generate_line(ary, row_sep: row_sep)
90
+ # Raises NoMethodError (undefined method `to_s' for #<BasicObject:>)
91
+ CSV.parse(str, row_sep: row_sep)
@@ -0,0 +1,31 @@
1
+ ====== Option +skip_blanks+
2
+
3
+ Specifies a boolean that determines whether blank lines in the input will be ignored;
4
+ a line that contains a column separator is not considered to be blank.
5
+
6
+ Default value:
7
+ CSV::DEFAULT_OPTIONS.fetch(:skip_blanks) # => false
8
+
9
+ See also option {skiplines}[#class-CSV-label-Option+skip_lines].
10
+
11
+ For examples in this section:
12
+ str = <<-EOT
13
+ foo,0
14
+
15
+ bar,1
16
+ baz,2
17
+
18
+ ,
19
+ EOT
20
+
21
+ Using the default, +false+:
22
+ ary = CSV.parse(str)
23
+ ary # => [["foo", "0"], [], ["bar", "1"], ["baz", "2"], [], [nil, nil]]
24
+
25
+ Using +true+:
26
+ ary = CSV.parse(str, skip_blanks: true)
27
+ ary # => [["foo", "0"], ["bar", "1"], ["baz", "2"], [nil, nil]]
28
+
29
+ Using a truthy value:
30
+ ary = CSV.parse(str, skip_blanks: :foo)
31
+ ary # => [["foo", "0"], ["bar", "1"], ["baz", "2"], [nil, nil]]
@@ -0,0 +1,37 @@
1
+ ====== Option +skip_lines+
2
+
3
+ Specifies an object to use in identifying comment lines in the input that are to be ignored:
4
+ * If a \Regexp, ignores lines that match it.
5
+ * If a \String, converts it to a \Regexp, ignores lines that match it.
6
+ * If +nil+, no lines are considered to be comments.
7
+
8
+ Default value:
9
+ CSV::DEFAULT_OPTIONS.fetch(:skip_lines) # => nil
10
+
11
+ For examples in this section:
12
+ str = <<-EOT
13
+ # Comment
14
+ foo,0
15
+ bar,1
16
+ baz,2
17
+ # Another comment
18
+ EOT
19
+ str # => "# Comment\nfoo,0\nbar,1\nbaz,2\n# Another comment\n"
20
+
21
+ Using the default, +nil+:
22
+ ary = CSV.parse(str)
23
+ ary # => [["# Comment"], ["foo", "0"], ["bar", "1"], ["baz", "2"], ["# Another comment"]]
24
+
25
+ Using a \Regexp:
26
+ ary = CSV.parse(str, skip_lines: /^#/)
27
+ ary # => [["foo", "0"], ["bar", "1"], ["baz", "2"]]
28
+
29
+ Using a \String:
30
+ ary = CSV.parse(str, skip_lines: '#')
31
+ ary # => [["foo", "0"], ["bar", "1"], ["baz", "2"]]
32
+
33
+ ---
34
+
35
+ Raises an exception if given an object that is not a \Regexp, a \String, or +nil+:
36
+ # Raises ArgumentError (:skip_lines has to respond to #match: 0)
37
+ CSV.parse(str, skip_lines: 0)
@@ -0,0 +1,15 @@
1
+ ====== Option +strip+
2
+
3
+ Specifies the boolean value that determines whether
4
+ whitespace is stripped from each input field.
5
+
6
+ Default value:
7
+ CSV::DEFAULT_OPTIONS.fetch(:strip) # => false
8
+
9
+ With default value +false+:
10
+ ary = CSV.parse_line(' a , b ')
11
+ ary # => [" a ", " b "]
12
+
13
+ With value +true+:
14
+ ary = CSV.parse_line(' a , b ', strip: true)
15
+ ary # => ["a", "b"]
@@ -0,0 +1,27 @@
1
+ ====== Option +unconverted_fields+
2
+
3
+ Specifies the boolean that determines whether unconverted field values are to be available.
4
+
5
+ Default value:
6
+ CSV::DEFAULT_OPTIONS.fetch(:unconverted_fields) # => nil
7
+
8
+ The unconverted field values are those found in the source data,
9
+ prior to any conversions performed via option +converters+.
10
+
11
+ When option +unconverted_fields+ is +true+,
12
+ each returned row (\Array or \CSV::Row) has an added method,
13
+ +unconverted_fields+, that returns the unconverted field values:
14
+ str = <<-EOT
15
+ foo,0
16
+ bar,1
17
+ baz,2
18
+ EOT
19
+ # Without unconverted_fields
20
+ csv = CSV.parse(str, converters: :integer)
21
+ csv # => [["foo", 0], ["bar", 1], ["baz", 2]]
22
+ csv.first.respond_to?(:unconverted_fields) # => false
23
+ # With unconverted_fields
24
+ csv = CSV.parse(str, converters: :integer, unconverted_fields: true)
25
+ csv # => [["foo", 0], ["bar", 1], ["baz", 2]]
26
+ csv.first.respond_to?(:unconverted_fields) # => true
27
+ csv.first.unconverted_fields # => ["foo", "0"]
@@ -0,0 +1,31 @@
1
+ ====== Option +write_converters+
2
+
3
+ Specifies the \Proc or \Array of Procs that are to be called
4
+ for converting each output field.
5
+
6
+ Default value:
7
+ CSV::DEFAULT_OPTIONS.fetch(:write_converters) # => nil
8
+
9
+ With no write converter:
10
+ str = CSV.generate_line(["\na\n", "\tb\t", " c "])
11
+ str # => "\"\na\n\",\tb\t, c \n"
12
+
13
+ With a write converter:
14
+ strip_converter = lambda {|field| field.strip }
15
+ str = CSV.generate_line(["\na\n", "\tb\t", " c "], write_converters: strip_converter)
16
+ str # => "a,b,c\n"
17
+
18
+ With two write converters (called in order):
19
+ upcase_converter = lambda {|field| field.upcase }
20
+ downcase_converter = lambda {|field| field.downcase }
21
+ write_converters = [upcase_converter, downcase_converter]
22
+ str = CSV.generate_line(['a', 'b', 'c'], write_converters: write_converters)
23
+ str # => "a,b,c\n"
24
+
25
+ ---
26
+
27
+ Raises an exception if the converter returns a value that is neither +nil+
28
+ nor \String-convertible:
29
+ bad_converter = lambda {|field| BasicObject.new }
30
+ # Raises NoMethodError (undefined method `is_a?' for #<BasicObject:>)
31
+ CSV.generate_line(['a', 'b', 'c'], write_converters: bad_converter)
@@ -0,0 +1,15 @@
1
+ ====== Option +write_empty_value+
2
+
3
+ Specifies the object that is to be substituted for each field
4
+ that has an empty \String.
5
+
6
+ Default value:
7
+ CSV::DEFAULT_OPTIONS.fetch(:write_empty_value) # => ""
8
+
9
+ Without the option:
10
+ str = CSV.generate_line(['a', '', 'c', ''])
11
+ str # => "a,\"\",c,\"\"\n"
12
+
13
+ With the option:
14
+ str = CSV.generate_line(['a', '', 'c', ''], write_empty_value: "x")
15
+ str # => "a,x,c,x\n"
@@ -0,0 +1,29 @@
1
+ ====== Option +write_headers+
2
+
3
+ Specifies the boolean that determines whether a header row is included in the output;
4
+ ignored if there are no headers.
5
+
6
+ Default value:
7
+ CSV::DEFAULT_OPTIONS.fetch(:write_headers) # => nil
8
+
9
+ Without +write_headers+:
10
+ file_path = 't.csv'
11
+ CSV.open(file_path,'w',
12
+ :headers => ['Name','Value']
13
+ ) do |csv|
14
+ csv << ['foo', '0']
15
+ end
16
+ CSV.open(file_path) do |csv|
17
+ csv.shift
18
+ end # => ["foo", "0"]
19
+
20
+ With +write_headers+":
21
+ CSV.open(file_path,'w',
22
+ :write_headers=> true,
23
+ :headers => ['Name','Value']
24
+ ) do |csv|
25
+ csv << ['foo', '0']
26
+ end
27
+ CSV.open(file_path) do |csv|
28
+ csv.shift
29
+ end # => ["Name", "Value"]
@@ -0,0 +1,14 @@
1
+ ====== Option +write_nil_value+
2
+
3
+ Specifies the object that is to be substituted for each +nil+ field.
4
+
5
+ Default value:
6
+ CSV::DEFAULT_OPTIONS.fetch(:write_nil_value) # => nil
7
+
8
+ Without the option:
9
+ str = CSV.generate_line(['a', nil, 'c', nil])
10
+ str # => "a,,c,\n"
11
+
12
+ With the option:
13
+ str = CSV.generate_line(['a', nil, 'c', nil], write_nil_value: "x")
14
+ str # => "a,x,c,x\n"
data/lib/csv.rb CHANGED
@@ -109,7 +109,7 @@ using CSV::MatchP if CSV.const_defined?(:MatchP)
109
109
  #
110
110
  # The most generic interface of the library is:
111
111
  #
112
- # csv = CSV.new(string_or_io, **options)
112
+ # csv = CSV.new(io, **options)
113
113
  #
114
114
  # # Reading: IO object should be open for read
115
115
  # csv.read # => array of rows
@@ -809,19 +809,37 @@ class CSV
809
809
  csv.string # return final String
810
810
  end
811
811
 
812
+ # :call-seq:
813
+ # CSV.generate_line(ary)
814
+ # CSV.generate_line(ary, **options)
812
815
  #
813
- # This method is a shortcut for converting a single row (Array) into a CSV
814
- # String.
816
+ # Returns the \String created by generating \CSV from +ary+
817
+ # using the specified +options+.
815
818
  #
816
- # See {Options for Generating}[#class-CSV-label-Options+for+Generating].
819
+ # Argument +ary+ must be an \Array.
820
+ #
821
+ # Special options:
822
+ # * Option <tt>:row_sep</tt> defaults to <tt>$INPUT_RECORD_SEPARATOR</tt>
823
+ # (<tt>$/</tt>).:
824
+ # $INPUT_RECORD_SEPARATOR # => "\n"
825
+ # * This method accepts an additional option, <tt>:encoding</tt>, which sets the base
826
+ # Encoding for the output. This method will try to guess your Encoding from
827
+ # the first non-+nil+ field in +row+, if possible, but you may need to use
828
+ # this parameter as a backup plan.
829
+ #
830
+ # For other +options+,
831
+ # see {Options for Generating}[#class-CSV-label-Options+for+Generating].
817
832
  #
818
- # This method accepts an additional option, <tt>:encoding</tt>, which sets the base
819
- # Encoding for the output. This method will try to guess your Encoding from
820
- # the first non-+nil+ field in +row+, if possible, but you may need to use
821
- # this parameter as a backup plan.
833
+ # ---
822
834
  #
823
- # The <tt>:row_sep</tt> +option+ defaults to <tt>$INPUT_RECORD_SEPARATOR</tt>
824
- # (<tt>$/</tt>) when calling this method.
835
+ # Returns the \String generated from an \Array:
836
+ # CSV.generate_line(['foo', '0']) # => "foo,0\n"
837
+ #
838
+ # ---
839
+ #
840
+ # Raises an exception if +ary+ is not an \Array:
841
+ # # Raises NoMethodError (undefined method `find' for :foo:Symbol)
842
+ # CSV.generate_line(:foo)
825
843
  #
826
844
  def generate_line(row, **options)
827
845
  options = {row_sep: $INPUT_RECORD_SEPARATOR}.merge(options)
@@ -955,12 +973,41 @@ class CSV
955
973
  end
956
974
  end
957
975
 
976
+ # :call-seq:
977
+ # CSV.parse_line(string)
978
+ # CSV.parse_line(io)
979
+ # CSV.parse_line(string, **options)
980
+ # CSV.parse_line(io, **options)
958
981
  #
959
- # This method is a shortcut for converting a single line of a CSV String into
960
- # an Array. Note that if +line+ contains multiple rows, anything beyond the
961
- # first row is ignored.
982
+ # Returns the new \Array created by parsing the first line of +string+ or +io+
983
+ # using the specified +options+.
962
984
  #
963
- # See {Options for Parsing}[#class-CSV-label-Options+for+Parsing].
985
+ # Argument +string+ should be a \String object;
986
+ # it will be put into a new \StringIO object positioned at the beginning.
987
+ #
988
+ # Argument +io+ should be an \IO object; it will be positioned at the beginning.
989
+ #
990
+ # For +options+, see {Options for Parsing}[#class-CSV-label-Options+for+Parsing].
991
+ #
992
+ # ---
993
+ # Returns data from the first line from a String object:
994
+ # CSV.parse_line('foo,0') # => ["foo", "0"]
995
+ #
996
+ # Returns data from the first line from a File object:
997
+ # File.write('t.csv', 'foo,0')
998
+ # CSV.parse_line(File.open('t.csv')) # => ["foo", "0"]
999
+ #
1000
+ # Ignores lines after the first:
1001
+ # CSV.parse_line("foo,0\nbar,1\nbaz,2") # => ["foo", "0"]
1002
+ #
1003
+ # Returns +nil+ if the argument is an empty \String:
1004
+ # CSV.parse_line('') # => nil
1005
+ #
1006
+ # ---
1007
+ #
1008
+ # Raises an exception if the argument is +nil+:
1009
+ # # Raises ArgumentError (Cannot parse nil as CSV):
1010
+ # CSV.parse_line(nil)
964
1011
  #
965
1012
  def parse_line(line, **options)
966
1013
  new(line, **options).each.first
@@ -1008,22 +1055,49 @@ class CSV
1008
1055
  end
1009
1056
  end
1010
1057
 
1058
+ # :call-seq:
1059
+ # CSV.new(string)
1060
+ # CSV.new(io)
1061
+ # CSV.new(string, **options)
1062
+ # CSV.new(io, **options)
1063
+ #
1064
+ # Returns the new \CSV object created using +string+ or +io+
1065
+ # and the specified +options+.
1066
+ #
1067
+ # Argument +string+ should be a \String object;
1068
+ # it will be put into a new \StringIO object positioned at the beginning.
1069
+ #
1070
+ # Argument +io+ should be an \IO object; it will be positioned at the beginning.
1071
+ #
1072
+ # To position at the end, for appending, use method CSV.generate.
1073
+ # For any other positioning, pass a preset StringIO object instead.
1074
+ #
1075
+ # In addition to the \CSV instance methods, several \IO
1076
+ # methods are delegated. See CSV::open for a complete list.
1077
+ #
1078
+ # For +options+, see:
1079
+ # * {Options for Parsing}[#class-CSV-label-Options+for+Parsing]
1080
+ # * {Options for Generating}[#class-CSV-label-Options+for+Generating]
1081
+ #
1082
+ # For performance reasons, the options cannot be overridden
1083
+ # in a \CSV object, so the options specified here will endure.
1084
+ #
1085
+ # ---
1011
1086
  #
1012
- # This constructor will wrap either a String or IO object passed in +data+ for
1013
- # reading and/or writing. In addition to the CSV instance methods, several IO
1014
- # methods are delegated. (See CSV::open() for a complete list.) If you pass
1015
- # a String for +data+, you can later retrieve it (after writing to it, for
1016
- # example) with CSV.string().
1087
+ # Create a \CSV object from a \String object:
1088
+ # csv = CSV.new('foo,0')
1089
+ # csv # => #<CSV io_type:StringIO encoding:UTF-8 lineno:0 col_sep:"," row_sep:"\n" quote_char:"\"">
1017
1090
  #
1018
- # Note that a wrapped String will be positioned at the beginning (for
1019
- # reading). If you want it at the end (for writing), use CSV::generate().
1020
- # If you want any other positioning, pass a preset StringIO object instead.
1091
+ # Create a \CSV object from a \File object:
1092
+ # File.write('t.csv', 'foo,0')
1093
+ # csv = CSV.new(File.open('t.csv'))
1094
+ # csv # => #<CSV io_type:File io_path:"t.csv" encoding:UTF-8 lineno:0 col_sep:"," row_sep:"\n" quote_char:"\"">
1021
1095
  #
1022
- # See {Options for Parsing}[#class-CSV-label-Options+for+Parsing]
1023
- # and {Options for Generating}[#class-CSV-label-Options+for+Generating].
1096
+ # ---
1024
1097
  #
1025
- # Options cannot be overridden in the instance methods for performance reasons,
1026
- # so be sure to set what you want here.
1098
+ # Raises an exception if the argument is +nil+:
1099
+ # # Raises ArgumentError (Cannot parse nil as CSV):
1100
+ # CSV.new(nil)
1027
1101
  #
1028
1102
  def initialize(data,
1029
1103
  col_sep: ",",
@@ -2,5 +2,5 @@
2
2
 
3
3
  class CSV
4
4
  # The version of the installed library.
5
- VERSION = "3.1.4"
5
+ VERSION = "3.1.5"
6
6
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: csv
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.1.4
4
+ version: 3.1.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - James Edward Gray II
@@ -75,11 +75,35 @@ email:
75
75
  - kou@cozmixng.org
76
76
  executables: []
77
77
  extensions: []
78
- extra_rdoc_files: []
78
+ extra_rdoc_files:
79
+ - LICENSE.txt
80
+ - NEWS.md
81
+ - README.md
79
82
  files:
80
83
  - LICENSE.txt
81
84
  - NEWS.md
82
85
  - README.md
86
+ - doc/col_sep.rdoc
87
+ - doc/converters.rdoc
88
+ - doc/empty_value.rdoc
89
+ - doc/field_size_limit.rdoc
90
+ - doc/force_quotes.rdoc
91
+ - doc/header_converters.rdoc
92
+ - doc/headers.rdoc
93
+ - doc/liberal_parsing.rdoc
94
+ - doc/nil_value.rdoc
95
+ - doc/quote_char.rdoc
96
+ - doc/quote_empty.rdoc
97
+ - doc/return_headers.rdoc
98
+ - doc/row_sep.rdoc
99
+ - doc/skip_blanks.rdoc
100
+ - doc/skip_lines.rdoc
101
+ - doc/strip.rdoc
102
+ - doc/unconverted_fields.rdoc
103
+ - doc/write_converters.rdoc
104
+ - doc/write_empty_value.rdoc
105
+ - doc/write_headers.rdoc
106
+ - doc/write_nil_value.rdoc
83
107
  - lib/csv.rb
84
108
  - lib/csv/core_ext/array.rb
85
109
  - lib/csv/core_ext/string.rb
@@ -96,7 +120,9 @@ licenses:
96
120
  - BSD-2-Clause
97
121
  metadata: {}
98
122
  post_install_message:
99
- rdoc_options: []
123
+ rdoc_options:
124
+ - "--main"
125
+ - README.md
100
126
  require_paths:
101
127
  - lib
102
128
  required_ruby_version: !ruby/object:Gem::Requirement