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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 44985560f2528c6909f94ce869ec8ddb014ee66d89fe940fe6f4c872f8773e97
4
- data.tar.gz: 60297accbe6a82852d251f5e4990dfacc241d6ec1084a39eb7ce39ac04c059d6
3
+ metadata.gz: bb25f2d0582cf6f7fd0677b63468bf268cc362f8fc45209376a08d3f93995b01
4
+ data.tar.gz: 32b3a6a958da3fbf005d0aea7217393befefe0da204ddf92b728c5c9514a1cce
5
5
  SHA512:
6
- metadata.gz: 7d51eae6f0e4eaccf382ffc52306ff9b9235259353c8514aafc3fd0116449ae342d9b5972e6ab236ddad542a9a286580f060080503fb18a2f81dfc97299cb8e8
7
- data.tar.gz: ef7d5e134f0ed59e4e0e466c5a6c4a6e45d51ff90a8e3bc22be1014041d29cb3a70c6ae7b482865426d5957962007875b734364b43742b2b7074548d3263bc76
6
+ metadata.gz: 77a56a3847636b8297007fa175c8e503933471b16ad8c34f3f676bc37af963d47101ee21eeb805cf1dd80201bce7117c20840bb94d25effb2e6bd299b2a5263d
7
+ data.tar.gz: 04b07a2b4f9dd23062caa1b7cfe0fe7e85c45176379806249abdf2151f866d919a1dda7337c0bef1459f5ebee846fde27efb1b67664fdd3f5ab15301a7ecffc1
data/NEWS.md CHANGED
@@ -1,5 +1,366 @@
1
1
  # News
2
2
 
3
+ ## 3.3.2 - 2024-12-21
4
+
5
+ ### Fixes
6
+
7
+ * Fixed a parse bug with a quoted line with `col_sep` and an empty
8
+ line. This was introduced in 3.3.1.
9
+ * GH-324
10
+ * Reported by stoodfarback
11
+
12
+ ### Thanks
13
+
14
+ * stoodfarback
15
+
16
+ ## 3.3.1 - 2024-12-15
17
+
18
+ ### Improvements
19
+
20
+ * `CSV.open`: Changed to detect BOM by default. Note that this isn't
21
+ enabled on Windows because Ruby may have a bug. See also:
22
+ https://bugs.ruby-lang.org/issues/20526
23
+ * GH-301
24
+ * Reported by Junichi Ito
25
+
26
+ * Improved performance.
27
+ * GH-311
28
+ * GH-312
29
+ * Patch by Vladimir Kochnev
30
+
31
+ * `CSV.open`: Added support for `StringIO` as an input.
32
+ * GH-300
33
+ * GH-302
34
+ * Patch by Marcelo
35
+
36
+ * Added a built-in time converter. You can use it by `converters:
37
+ :time`.
38
+ * GH-313
39
+ * Patch by Bart de Water
40
+
41
+ * Added `CSV::TSV` for tab-separated values.
42
+ * GH-272
43
+ * GH-319
44
+ * Reported by kojix2
45
+ * Patch by Jas
46
+
47
+ ### Thanks
48
+
49
+ * Junichi Ito
50
+
51
+ * Vladimir Kochnev
52
+
53
+ * Marcelo
54
+
55
+ * Bart de Water
56
+
57
+ * kojix2
58
+
59
+ * Jas
60
+
61
+ ## 3.3.0 - 2024-03-22
62
+
63
+ ### Fixes
64
+
65
+ * Fixed a regression parse bug in 3.2.9 that parsing with
66
+ `:skip_lines` may cause wrong result.
67
+
68
+ ## 3.2.9 - 2024-03-22
69
+
70
+ ### Fixes
71
+
72
+ * Fixed a parse bug that wrong result may be happen when:
73
+
74
+ * `:skip_lines` is used
75
+ * `:row_separator` is `"\r\n"`
76
+ * There is a line that includes `\n` as a column value
77
+
78
+ Reported by Ryo Tsukamoto.
79
+
80
+ GH-296
81
+
82
+ ### Thanks
83
+
84
+ * Ryo Tsukamoto
85
+
86
+ ## 3.2.8 - 2023-11-08
87
+
88
+ ### Improvements
89
+
90
+ * Added `CSV::InvalidEncodingError`.
91
+
92
+ Patch by Kosuke Shibata.
93
+
94
+ GH-287
95
+
96
+ ### Thanks
97
+
98
+ * Kosuke Shibata
99
+
100
+ ## 3.2.7 - 2023-06-26
101
+
102
+ ### Improvements
103
+
104
+ * Removed an unused internal variable.
105
+ [GH-273](https://github.com/ruby/csv/issues/273)
106
+ [Patch by Mau Magnaguagno]
107
+
108
+ * Changed to use `https://` instead of `http://` in documents.
109
+ [GH-274](https://github.com/ruby/csv/issues/274)
110
+ [Patch by Vivek Bharath Akupatni]
111
+
112
+ * Added prefix to a helper module in test.
113
+ [GH-278](https://github.com/ruby/csv/issues/278)
114
+ [Patch by Luke Gruber]
115
+
116
+ * Added a documentation for `liberal_parsing: {backslash_quotes: true}`.
117
+ [GH-280](https://github.com/ruby/csv/issues/280)
118
+ [Patch by Mark Schneider]
119
+
120
+ ### Fixes
121
+
122
+ * Fixed a wrong execution result in documents.
123
+ [GH-276](https://github.com/ruby/csv/issues/276)
124
+ [Patch by Yuki Tsujimoto]
125
+
126
+ * Fixed a bug that the same line is used multiple times.
127
+ [GH-279](https://github.com/ruby/csv/issues/279)
128
+ [Reported by Gabriel Nagy]
129
+
130
+ ### Thanks
131
+
132
+ * Mau Magnaguagno
133
+
134
+ * Vivek Bharath Akupatni
135
+
136
+ * Yuki Tsujimoto
137
+
138
+ * Luke Gruber
139
+
140
+ * Mark Schneider
141
+
142
+ * Gabriel Nagy
143
+
144
+ ## 3.2.6 - 2022-12-08
145
+
146
+ ### Improvements
147
+
148
+ * `CSV#read` consumes the same lines with other methods like
149
+ `CSV#shift`.
150
+ [[GitHub#258](https://github.com/ruby/csv/issues/258)]
151
+ [Reported by Lhoussaine Ghallou]
152
+
153
+ * All `Enumerable` based methods consume the same lines with other
154
+ methods. This may have a performance penalty.
155
+ [[GitHub#260](https://github.com/ruby/csv/issues/260)]
156
+ [Reported by Lhoussaine Ghallou]
157
+
158
+ * Simplify some implementations.
159
+ [[GitHub#262](https://github.com/ruby/csv/pull/262)]
160
+ [[GitHub#263](https://github.com/ruby/csv/pull/263)]
161
+ [Patch by Mau Magnaguagno]
162
+
163
+ ### Fixes
164
+
165
+ * Fixed `CSV.generate_lines` document.
166
+ [[GitHub#257](https://github.com/ruby/csv/pull/257)]
167
+ [Patch by Sampat Badhe]
168
+
169
+ ### Thanks
170
+
171
+ * Sampat Badhe
172
+
173
+ * Lhoussaine Ghallou
174
+
175
+ * Mau Magnaguagno
176
+
177
+ ## 3.2.5 - 2022-08-26
178
+
179
+ ### Improvements
180
+
181
+ * Added `CSV.generate_lines`.
182
+ [[GitHub#255](https://github.com/ruby/csv/issues/255)]
183
+ [Reported by OKURA Masafumi]
184
+ [[GitHub#256](https://github.com/ruby/csv/pull/256)]
185
+ [Patch by Eriko Sugiyama]
186
+
187
+ ### Thanks
188
+
189
+ * OKURA Masafumi
190
+
191
+ * Eriko Sugiyama
192
+
193
+ ## 3.2.4 - 2022-08-22
194
+
195
+ ### Improvements
196
+
197
+ * Cleaned up internal implementations.
198
+ [[GitHub#249](https://github.com/ruby/csv/pull/249)]
199
+ [[GitHub#250](https://github.com/ruby/csv/pull/250)]
200
+ [[GitHub#251](https://github.com/ruby/csv/pull/251)]
201
+ [Patch by Mau Magnaguagno]
202
+
203
+ * Added support for RFC 3339 style time.
204
+ [[GitHub#248](https://github.com/ruby/csv/pull/248)]
205
+ [Patch by Thierry Lambert]
206
+
207
+ * Added support for transcoding String CSV. Syntax is
208
+ `from-encoding:to-encoding`.
209
+ [[GitHub#254](https://github.com/ruby/csv/issues/254)]
210
+ [Reported by Richard Stueven]
211
+
212
+ * Added quoted information to `CSV::FieldInfo`.
213
+ [[GitHub#254](https://github.com/ruby/csv/pull/253)]
214
+ [Reported by Hirokazu SUZUKI]
215
+
216
+ ### Fixes
217
+
218
+ * Fixed a link in documents.
219
+ [[GitHub#244](https://github.com/ruby/csv/pull/244)]
220
+ [Patch by Peter Zhu]
221
+
222
+ ### Thanks
223
+
224
+ * Peter Zhu
225
+
226
+ * Mau Magnaguagno
227
+
228
+ * Thierry Lambert
229
+
230
+ * Richard Stueven
231
+
232
+ * Hirokazu SUZUKI
233
+
234
+ ## 3.2.3 - 2022-04-09
235
+
236
+ ### Improvements
237
+
238
+ * Added contents summary to `CSV::Table#inspect`.
239
+ [GitHub#229][Patch by Eriko Sugiyama]
240
+ [GitHub#235][Patch by Sampat Badhe]
241
+
242
+ * Suppressed `$INPUT_RECORD_SEPARATOR` deprecation warning by
243
+ `Warning.warn`.
244
+ [GitHub#233][Reported by Jean byroot Boussier]
245
+
246
+ * Improved error message for liberal parsing with quoted values.
247
+ [GitHub#231][Patch by Nikolay Rys]
248
+
249
+ * Fixed typos in documentation.
250
+ [GitHub#236][Patch by Sampat Badhe]
251
+
252
+ * Added `:max_field_size` option and deprecated `:field_size_limit` option.
253
+ [GitHub#238][Reported by Dan Buettner]
254
+
255
+ * Added `:symbol_raw` to built-in header converters.
256
+ [GitHub#237][Reported by taki]
257
+ [GitHub#239][Patch by Eriko Sugiyama]
258
+
259
+ ### Fixes
260
+
261
+ * Fixed a bug that some texts may be dropped unexpectedly.
262
+ [Bug #18245][ruby-core:105587][Reported by Hassan Abdul Rehman]
263
+
264
+ * Fixed a bug that `:field_size_limit` doesn't work with not complex row.
265
+ [GitHub#238][Reported by Dan Buettner]
266
+
267
+ ### Thanks
268
+
269
+ * Hassan Abdul Rehman
270
+
271
+ * Eriko Sugiyama
272
+
273
+ * Jean byroot Boussier
274
+
275
+ * Nikolay Rys
276
+
277
+ * Sampat Badhe
278
+
279
+ * Dan Buettner
280
+
281
+ * taki
282
+
283
+ ## 3.2.2 - 2021-12-24
284
+
285
+ ### Improvements
286
+
287
+ * Added a validation for invalid option combination.
288
+ [GitHub#225][Patch by adamroyjones]
289
+
290
+ * Improved documentation for developers.
291
+ [GitHub#227][Patch by Eriko Sugiyama]
292
+
293
+ ### Fixes
294
+
295
+ * Fixed a bug that all of `ARGF` contents may not be consumed.
296
+ [GitHub#228][Reported by Rafael Navaza]
297
+
298
+ ### Thanks
299
+
300
+ * adamroyjones
301
+
302
+ * Eriko Sugiyama
303
+
304
+ * Rafael Navaza
305
+
306
+ ## 3.2.1 - 2021-10-23
307
+
308
+ ### Improvements
309
+
310
+ * doc: Fixed wrong class name.
311
+ [GitHub#217][Patch by Vince]
312
+
313
+ * Changed to always use `"\n"` for the default row separator on Ruby
314
+ 3.0 or later because `$INPUT_RECORD_SEPARATOR` was deprecated
315
+ since Ruby 3.0.
316
+
317
+ * Added support for Ractor.
318
+ [GitHub#218][Patch by rm155]
319
+
320
+ * Users who want to use the built-in converters in non-main
321
+ Ractors need to call `Ractor.make_shareable(CSV::Converters)`
322
+ and/or `Ractor.make_shareable(CSV::HeaderConverters)` before
323
+ creating non-main Ractors.
324
+
325
+ ### Thanks
326
+
327
+ * Vince
328
+
329
+ * Joakim Antman
330
+
331
+ * rm155
332
+
333
+ ## 3.2.0 - 2021-06-06
334
+
335
+ ### Improvements
336
+
337
+ * `CSV.open`: Added support for `:newline` option.
338
+ [GitHub#198][Patch by Nobuyoshi Nakada]
339
+
340
+ * `CSV::Table#each`: Added support for column mode with duplicated
341
+ headers.
342
+ [GitHub#206][Reported by Yaroslav Berezovskiy]
343
+
344
+ * `Object#CSV`: Added support for Ruby 3.0.
345
+
346
+ * `CSV::Row`: Added support for pattern matching.
347
+ [GitHub#207][Patch by Kevin Newton]
348
+
349
+ ### Fixes
350
+
351
+ * Fixed typos in documentation.
352
+ [GitHub#196][GitHub#205][Patch by Sampat Badhe]
353
+
354
+ ### Thanks
355
+
356
+ * Sampat Badhe
357
+
358
+ * Nobuyoshi Nakada
359
+
360
+ * Yaroslav Berezovskiy
361
+
362
+ * Kevin Newton
363
+
3
364
  ## 3.1.9 - 2020-11-23
4
365
 
5
366
  ### Fixes
data/README.md CHANGED
@@ -1,8 +1,5 @@
1
1
  # CSV
2
2
 
3
- [![Build Status](https://travis-ci.org/ruby/csv.svg?branch=master)](https://travis-ci.org/ruby/csv)
4
- [![Test Coverage](https://api.codeclimate.com/v1/badges/321fa39e510a0abd0369/test_coverage)](https://codeclimate.com/github/ruby/csv/test_coverage)
5
-
6
3
  This library provides a complete interface to CSV files and data. It offers tools to enable you to read and write to and from Strings or IO objects, as needed.
7
4
 
8
5
  ## Installation
@@ -33,12 +30,12 @@ end
33
30
 
34
31
  ## Documentation
35
32
 
36
- - {API}[CSV.html]: all classes, methods, and constants.
37
- - {Recipes}[doc/csv/recipes/recipes_rdoc.html]: specific code for specific tasks.
33
+ - [API](https://ruby.github.io/csv/): all classes, methods, and constants.
34
+ - [Recipes](https://ruby.github.io/csv/doc/csv/recipes/recipes_rdoc.html): specific code for specific tasks.
38
35
 
39
36
  ## Development
40
37
 
41
- After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
38
+ After checking out the repo, run `ruby run-test.rb` to check if your changes can pass the test.
42
39
 
43
40
  To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
44
41
 
@@ -19,7 +19,7 @@ Without +write_headers+:
19
19
 
20
20
  With +write_headers+":
21
21
  CSV.open(file_path,'w',
22
- :write_headers=> true,
22
+ :write_headers => true,
23
23
  :headers => ['Name','Value']
24
24
  ) do |csv|
25
25
  csv << ['foo', '0']
@@ -1,13 +1,13 @@
1
1
  ====== Option +liberal_parsing+
2
2
 
3
- Specifies the boolean value that determines whether
3
+ Specifies the boolean or hash value that determines whether
4
4
  CSV will attempt to parse input not conformant with RFC 4180,
5
5
  such as double quotes in unquoted fields.
6
6
 
7
7
  Default value:
8
8
  CSV::DEFAULT_OPTIONS.fetch(:liberal_parsing) # => false
9
9
 
10
- For examples in this section:
10
+ For the next two examples:
11
11
  str = 'is,this "three, or four",fields'
12
12
 
13
13
  Without +liberal_parsing+:
@@ -17,3 +17,22 @@ Without +liberal_parsing+:
17
17
  With +liberal_parsing+:
18
18
  ary = CSV.parse_line(str, liberal_parsing: true)
19
19
  ary # => ["is", "this \"three", " or four\"", "fields"]
20
+
21
+ Use the +backslash_quote+ sub-option to parse values that use
22
+ a backslash to escape a double-quote character. This
23
+ causes the parser to treat <code>\"</code> as if it were
24
+ <code>""</code>.
25
+
26
+ For the next two examples:
27
+ str = 'Show,"Harry \"Handcuff\" Houdini, the one and only","Tampa Theater"'
28
+
29
+ With +liberal_parsing+, but without the +backslash_quote+ sub-option:
30
+ # Incorrect interpretation of backslash; incorrectly interprets the quoted comma as a field separator.
31
+ ary = CSV.parse_line(str, liberal_parsing: true)
32
+ ary # => ["Show", "\"Harry \\\"Handcuff\\\" Houdini", " the one and only\"", "Tampa Theater"]
33
+ puts ary[1] # => "Harry \"Handcuff\" Houdini
34
+
35
+ With +liberal_parsing+ and its +backslash_quote+ sub-option:
36
+ ary = CSV.parse_line(str, liberal_parsing: { backslash_quote: true })
37
+ ary # => ["Show", "Harry \"Handcuff\" Houdini, the one and only", "Tampa Theater"]
38
+ puts ary[1] # => Harry "Handcuff" Houdini, the one and only
@@ -11,16 +11,20 @@ All code snippets on this page assume that the following has been executed:
11
11
 
12
12
  - {Source and Output Formats}[#label-Source+and+Output+Formats]
13
13
  - {Filtering String to String}[#label-Filtering+String+to+String]
14
- - {Recipe: Filter String to String with Headers}[#label-Recipe-3A+Filter+String+to+String+with+Headers]
14
+ - {Recipe: Filter String to String parsing Headers}[#label-Recipe-3A+Filter+String+to+String+parsing+Headers]
15
+ - {Recipe: Filter String to String parsing and writing Headers}[#label-Recipe-3A+Filter+String+to+String+parsing+and+writing+Headers]
15
16
  - {Recipe: Filter String to String Without Headers}[#label-Recipe-3A+Filter+String+to+String+Without+Headers]
16
17
  - {Filtering String to IO Stream}[#label-Filtering+String+to+IO+Stream]
17
- - {Recipe: Filter String to IO Stream with Headers}[#label-Recipe-3A+Filter+String+to+IO+Stream+with+Headers]
18
+ - {Recipe: Filter String to IO Stream parsing Headers}[#label-Recipe-3A+Filter+String+to+IO+Stream+parsing+Headers]
19
+ - {Recipe: Filter String to IO Stream parsing and writing Headers}[#label-Recipe-3A+Filter+String+to+IO+Stream+parsing+and+writing+Headers]
18
20
  - {Recipe: Filter String to IO Stream Without Headers}[#label-Recipe-3A+Filter+String+to+IO+Stream+Without+Headers]
19
21
  - {Filtering IO Stream to String}[#label-Filtering+IO+Stream+to+String]
20
- - {Recipe: Filter IO Stream to String with Headers}[#label-Recipe-3A+Filter+IO+Stream+to+String+with+Headers]
22
+ - {Recipe: Filter IO Stream to String parsing Headers}[#label-Recipe-3A+Filter+IO+Stream+to+String+parsing+Headers]
23
+ - {Recipe: Filter IO Stream to String parsing and writing Headers}[#label-Recipe-3A+Filter+IO+Stream+to+String+parsing+and+writing+Headers]
21
24
  - {Recipe: Filter IO Stream to String Without Headers}[#label-Recipe-3A+Filter+IO+Stream+to+String+Without+Headers]
22
25
  - {Filtering IO Stream to IO Stream}[#label-Filtering+IO+Stream+to+IO+Stream]
23
- - {Recipe: Filter IO Stream to IO Stream with Headers}[#label-Recipe-3A+Filter+IO+Stream+to+IO+Stream+with+Headers]
26
+ - {Recipe: Filter IO Stream to IO Stream parsing Headers}[#label-Recipe-3A+Filter+IO+Stream+to+IO+Stream+parsing+Headers]
27
+ - {Recipe: Filter IO Stream to IO Stream parsing and writing Headers}[#label-Recipe-3A+Filter+IO+Stream+to+IO+Stream+parsing+and+writing+Headers]
24
28
  - {Recipe: Filter IO Stream to IO Stream Without Headers}[#label-Recipe-3A+Filter+IO+Stream+to+IO+Stream+Without+Headers]
25
29
 
26
30
  === Source and Output Formats
@@ -33,14 +37,27 @@ The input and output \CSV data may be any mixture of \Strings and \IO streams.
33
37
 
34
38
  You can filter one \String to another, with or without headers.
35
39
 
36
- ===== Recipe: Filter \String to \String with Headers
40
+ ===== Recipe: Filter \String to \String parsing Headers
37
41
 
38
42
  Use class method CSV.filter with option +headers+ to filter a \String to another \String:
39
43
  in_string = "Name,Value\nfoo,0\nbar,1\nbaz,2\n"
40
44
  out_string = ''
41
45
  CSV.filter(in_string, out_string, headers: true) do |row|
42
- row[0] = row[0].upcase
43
- row[1] *= 4
46
+ row['Name'] = row['Name'].upcase
47
+ row['Value'] *= 4
48
+ end
49
+ out_string # => "FOO,0000\nBAR,1111\nBAZ,2222\n"
50
+
51
+ ===== Recipe: Filter \String to \String parsing and writing Headers
52
+
53
+ Use class method CSV.filter with option +headers+ and +out_write_headers+ to filter a \String to another \String including header row:
54
+ in_string = "Name,Value\nfoo,0\nbar,1\nbaz,2\n"
55
+ out_string = ''
56
+ CSV.filter(in_string, out_string, headers: true, out_write_headers: true) do |row|
57
+ unless row.is_a?(Array)
58
+ row['Name'] = row['Name'].upcase
59
+ row['Value'] *= 4
60
+ end
44
61
  end
45
62
  out_string # => "Name,Value\nFOO,0000\nBAR,1111\nBAZ,2222\n"
46
63
 
@@ -59,15 +76,30 @@ Use class method CSV.filter without option +headers+ to filter a \String to anot
59
76
 
60
77
  You can filter a \String to an \IO stream, with or without headers.
61
78
 
62
- ===== Recipe: Filter \String to \IO Stream with Headers
79
+ ===== Recipe: Filter \String to \IO Stream parsing Headers
63
80
 
64
81
  Use class method CSV.filter with option +headers+ to filter a \String to an \IO stream:
65
82
  in_string = "Name,Value\nfoo,0\nbar,1\nbaz,2\n"
66
83
  path = 't.csv'
67
84
  File.open(path, 'w') do |out_io|
68
85
  CSV.filter(in_string, out_io, headers: true) do |row|
69
- row[0] = row[0].upcase
70
- row[1] *= 4
86
+ row['Name'] = row['Name'].upcase
87
+ row['Value'] *= 4
88
+ end
89
+ end
90
+ p File.read(path) # => "FOO,0000\nBAR,1111\nBAZ,2222\n"
91
+
92
+ ===== Recipe: Filter \String to \IO Stream parsing and writing Headers
93
+
94
+ Use class method CSV.filter with option +headers+ and +out_write_headers+ to filter a \String to an \IO stream including header row:
95
+ in_string = "Name,Value\nfoo,0\nbar,1\nbaz,2\n"
96
+ path = 't.csv'
97
+ File.open(path, 'w') do |out_io|
98
+ CSV.filter(in_string, out_io, headers: true, out_write_headers: true ) do |row|
99
+ unless row.is_a?(Array)
100
+ row['Name'] = row['Name'].upcase
101
+ row['Value'] *= 4
102
+ end
71
103
  end
72
104
  end
73
105
  p File.read(path) # => "Name,Value\nFOO,0000\nBAR,1111\nBAZ,2222\n"
@@ -89,17 +121,34 @@ Use class method CSV.filter without option +headers+ to filter a \String to an \
89
121
 
90
122
  You can filter an \IO stream to a \String, with or without headers.
91
123
 
92
- ===== Recipe: Filter \IO Stream to \String with Headers
124
+ ===== Recipe: Filter \IO Stream to \String parsing Headers
93
125
 
94
126
  Use class method CSV.filter with option +headers+ to filter an \IO stream to a \String:
95
127
  in_string = "Name,Value\nfoo,0\nbar,1\nbaz,2\n"
96
128
  path = 't.csv'
97
129
  File.write(path, in_string)
98
130
  out_string = ''
99
- File.open(path, headers: true) do |in_io|
131
+ File.open(path) do |in_io|
100
132
  CSV.filter(in_io, out_string, headers: true) do |row|
101
- row[0] = row[0].upcase
102
- row[1] *= 4
133
+ row['Name'] = row['Name'].upcase
134
+ row['Value'] *= 4
135
+ end
136
+ end
137
+ out_string # => "FOO,0000\nBAR,1111\nBAZ,2222\n"
138
+
139
+ ===== Recipe: Filter \IO Stream to \String parsing and writing Headers
140
+
141
+ Use class method CSV.filter with option +headers+ and +out_write_headers+ to filter an \IO stream to a \String including header row:
142
+ in_string = "Name,Value\nfoo,0\nbar,1\nbaz,2\n"
143
+ path = 't.csv'
144
+ File.write(path, in_string)
145
+ out_string = ''
146
+ File.open(path) do |in_io|
147
+ CSV.filter(in_io, out_string, headers: true, out_write_headers: true) do |row|
148
+ unless row.is_a?(Array)
149
+ row['Name'] = row['Name'].upcase
150
+ row['Value'] *= 4
151
+ end
103
152
  end
104
153
  end
105
154
  out_string # => "Name,Value\nFOO,0000\nBAR,1111\nBAZ,2222\n"
@@ -123,7 +172,7 @@ Use class method CSV.filter without option +headers+ to filter an \IO stream to
123
172
 
124
173
  You can filter an \IO stream to another \IO stream, with or without headers.
125
174
 
126
- ===== Recipe: Filter \IO Stream to \IO Stream with Headers
175
+ ===== Recipe: Filter \IO Stream to \IO Stream parsing Headers
127
176
 
128
177
  Use class method CSV.filter with option +headers+ to filter an \IO stream to another \IO stream:
129
178
  in_path = 't.csv'
@@ -133,8 +182,27 @@ Use class method CSV.filter with option +headers+ to filter an \IO stream to ano
133
182
  File.open(in_path) do |in_io|
134
183
  File.open(out_path, 'w') do |out_io|
135
184
  CSV.filter(in_io, out_io, headers: true) do |row|
136
- row[0] = row[0].upcase
137
- row[1] *= 4
185
+ row['Name'] = row['Name'].upcase
186
+ row['Value'] *= 4
187
+ end
188
+ end
189
+ end
190
+ p File.read(out_path) # => "FOO,0000\nBAR,1111\nBAZ,2222\n"
191
+
192
+ ===== Recipe: Filter \IO Stream to \IO Stream parsing and writing Headers
193
+
194
+ Use class method CSV.filter with option +headers+ and +out_write_headers+ to filter an \IO stream to another \IO stream including header row:
195
+ in_path = 't.csv'
196
+ in_string = "Name,Value\nfoo,0\nbar,1\nbaz,2\n"
197
+ File.write(in_path, in_string)
198
+ out_path = 'u.csv'
199
+ File.open(in_path) do |in_io|
200
+ File.open(out_path, 'w') do |out_io|
201
+ CSV.filter(in_io, out_io, headers: true, out_write_headers: true) do |row|
202
+ unless row.is_a?(Array)
203
+ row['Name'] = row['Name'].upcase
204
+ row['Value'] *= 4
205
+ end
138
206
  end
139
207
  end
140
208
  end
@@ -148,7 +148,7 @@ This example defines and uses a custom write converter to strip whitespace from
148
148
 
149
149
  ==== Recipe: Specify Multiple Write Converters
150
150
 
151
- Use option <tt>:write_converters</tt> and multiple custom coverters
151
+ Use option <tt>:write_converters</tt> and multiple custom converters
152
152
  to convert field values when generating \CSV.
153
153
 
154
154
  This example defines and uses two custom write converters to strip and upcase generated fields:
@@ -165,7 +165,7 @@ This example defines and uses two custom write converters to strip and upcase ge
165
165
  === RFC 4180 Compliance
166
166
 
167
167
  By default, \CSV generates data that is compliant with
168
- {RFC 4180}[https://tools.ietf.org/html/rfc4180]
168
+ {RFC 4180}[https://www.rfc-editor.org/rfc/rfc4180]
169
169
  with respect to:
170
170
  - Column separator.
171
171
  - Quote character.