csv 3.1.3 → 3.1.4
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 +25 -0
- data/lib/csv.rb +323 -217
- data/lib/csv/fields_converter.rb +1 -1
- data/lib/csv/parser.rb +1 -1
- data/lib/csv/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: dad2154faebc0d08b471d1f5624752997374f8472dc2408756d7a78efb87d9c9
|
4
|
+
data.tar.gz: 9c6e071bcf07ab25aa0ff068030b42dbb47968d9f9e7aa5b04a1ff33ed12c2ea
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4da5b31e15b5c215d1f346c330a3d86ebea640cc4af4c33bd0aa238ac4b9b5cde2c72fc7edcd045de60f4cacb49a5ed8cbbf8a963a1a0750d16f5472faa95c1c
|
7
|
+
data.tar.gz: 83ee56fae5acb6afdb8d722e0c0182f17112a157a2ab6ad0b30a60d524fd146850a1afe360217c2e2b5af36335668716289612ae1817d98c77b2ea2c5d610240
|
data/NEWS.md
CHANGED
@@ -1,5 +1,30 @@
|
|
1
1
|
# News
|
2
2
|
|
3
|
+
## 3.1.4 - 2020-05-17
|
4
|
+
|
5
|
+
### Improvements
|
6
|
+
|
7
|
+
* Improved document.
|
8
|
+
[GitHub#122][Patch by Burdette Lamar]
|
9
|
+
|
10
|
+
* Stopped to dropping stack trace for exception caused by
|
11
|
+
`CSV.parse_line`.
|
12
|
+
[GitHub#120][Reported by Kyle d'Oliveira]
|
13
|
+
|
14
|
+
### Fixes
|
15
|
+
|
16
|
+
* Fixed a bug that `:write_nil_value` or `:write_empty_value` don't
|
17
|
+
work with non `String` objects.
|
18
|
+
[GitHub#123][Reported by asm256]
|
19
|
+
|
20
|
+
### Thanks
|
21
|
+
|
22
|
+
* Burdette Lamar
|
23
|
+
|
24
|
+
* asm256
|
25
|
+
|
26
|
+
* Kyle d'Oliveira
|
27
|
+
|
3
28
|
## 3.1.3 - 2020-05-09
|
4
29
|
|
5
30
|
### Improvements
|
data/lib/csv.rb
CHANGED
@@ -103,7 +103,6 @@ require_relative "csv/writer"
|
|
103
103
|
|
104
104
|
using CSV::MatchP if CSV.const_defined?(:MatchP)
|
105
105
|
|
106
|
-
#
|
107
106
|
# This class provides a complete interface to CSV files and data. It offers
|
108
107
|
# tools to enable you to read and write to and from Strings or IO objects, as
|
109
108
|
# needed.
|
@@ -179,9 +178,89 @@ using CSV::MatchP if CSV.const_defined?(:MatchP)
|
|
179
178
|
# CSV($stderr) { |csv_err| csv_err << %w{my data here} } # to $stderr
|
180
179
|
# CSV($stdin) { |csv_in| csv_in.each { |row| p row } } # from $stdin
|
181
180
|
#
|
182
|
-
# ==
|
181
|
+
# == Options
|
182
|
+
#
|
183
|
+
# The default values for options are:
|
184
|
+
# DEFAULT_OPTIONS = {
|
185
|
+
# # For both parsing and generating.
|
186
|
+
# col_sep: ",",
|
187
|
+
# row_sep: :auto,
|
188
|
+
# quote_char: '"',
|
189
|
+
# # For parsing.
|
190
|
+
# field_size_limit: nil,
|
191
|
+
# converters: nil,
|
192
|
+
# unconverted_fields: nil,
|
193
|
+
# headers: false,
|
194
|
+
# return_headers: false,
|
195
|
+
# header_converters: nil,
|
196
|
+
# skip_blanks: false,
|
197
|
+
# skip_lines: nil,
|
198
|
+
# liberal_parsing: false,
|
199
|
+
# nil_value: nil,
|
200
|
+
# empty_value: "",
|
201
|
+
# # For generating.
|
202
|
+
# write_headers: nil,
|
203
|
+
# quote_empty: true,
|
204
|
+
# force_quotes: false,
|
205
|
+
# write_converters: nil,
|
206
|
+
# write_nil_value: nil,
|
207
|
+
# write_empty_value: "",
|
208
|
+
# strip: false,
|
209
|
+
# }
|
210
|
+
#
|
211
|
+
# === Options for Parsing
|
212
|
+
#
|
213
|
+
# :include: ../doc/col_sep.rdoc
|
214
|
+
#
|
215
|
+
# :include: ../doc/row_sep.rdoc
|
216
|
+
#
|
217
|
+
# :include: ../doc/quote_char.rdoc
|
218
|
+
#
|
219
|
+
# :include: ../doc/field_size_limit.rdoc
|
220
|
+
#
|
221
|
+
# :include: ../doc/converters.rdoc
|
222
|
+
#
|
223
|
+
# :include: ../doc/unconverted_fields.rdoc
|
224
|
+
#
|
225
|
+
# :include: ../doc/headers.rdoc
|
226
|
+
#
|
227
|
+
# :include: ../doc/return_headers.rdoc
|
228
|
+
#
|
229
|
+
# :include: ../doc/header_converters.rdoc
|
230
|
+
#
|
231
|
+
# :include: ../doc/skip_blanks.rdoc
|
232
|
+
#
|
233
|
+
# :include: ../doc/skip_lines.rdoc
|
234
|
+
#
|
235
|
+
# :include: ../doc/liberal_parsing.rdoc
|
236
|
+
#
|
237
|
+
# :include: ../doc/nil_value.rdoc
|
238
|
+
#
|
239
|
+
# :include: ../doc/empty_value.rdoc
|
240
|
+
#
|
241
|
+
# === Options for Generating
|
242
|
+
#
|
243
|
+
# :include: ../doc/col_sep.rdoc
|
244
|
+
#
|
245
|
+
# :include: ../doc/row_sep.rdoc
|
246
|
+
#
|
247
|
+
# :include: ../doc/quote_char.rdoc
|
248
|
+
#
|
249
|
+
# :include: ../doc/write_headers.rdoc
|
250
|
+
#
|
251
|
+
# :include: ../doc/force_quotes.rdoc
|
183
252
|
#
|
184
|
-
#
|
253
|
+
# :include: ../doc/quote_empty.rdoc
|
254
|
+
#
|
255
|
+
# :include: ../doc/write_converters.rdoc
|
256
|
+
#
|
257
|
+
# :include: ../doc/write_nil_value.rdoc
|
258
|
+
#
|
259
|
+
# :include: ../doc/write_empty_value.rdoc
|
260
|
+
#
|
261
|
+
# :include: ../doc/strip.rdoc
|
262
|
+
#
|
263
|
+
# == CSV with headers
|
185
264
|
#
|
186
265
|
# CSV allows to specify column names of CSV file, whether they are in data, or
|
187
266
|
# provided separately. If headers are specified, reading methods return an instance
|
@@ -203,22 +282,205 @@ using CSV::MatchP if CSV.const_defined?(:MatchP)
|
|
203
282
|
# data = CSV.parse('Bob,Engineering,1000', headers: %i[name department salary])
|
204
283
|
# data.first #=> #<CSV::Row name:"Bob" department:"Engineering" salary:"1000">
|
205
284
|
#
|
206
|
-
#
|
207
|
-
#
|
208
|
-
#
|
209
|
-
#
|
210
|
-
#
|
211
|
-
#
|
212
|
-
#
|
213
|
-
#
|
214
|
-
#
|
215
|
-
#
|
216
|
-
#
|
217
|
-
#
|
218
|
-
#
|
219
|
-
#
|
220
|
-
#
|
221
|
-
#
|
285
|
+
# == \CSV \Converters
|
286
|
+
#
|
287
|
+
# By default, each field parsed by \CSV is formed into a \String.
|
288
|
+
# You can use a _converter_ to convert certain fields into other Ruby objects.
|
289
|
+
#
|
290
|
+
# When you specify a converter for parsing,
|
291
|
+
# each parsed field is passed to the converter;
|
292
|
+
# its return value becomes the new value for the field.
|
293
|
+
# A converter might, for example, convert an integer embedded in a \String
|
294
|
+
# into a true \Integer.
|
295
|
+
# (In fact, that's what built-in field converter +:integer+ does.)
|
296
|
+
#
|
297
|
+
# There are additional built-in \converters, and custom \converters are also supported.
|
298
|
+
#
|
299
|
+
# All \converters try to transcode fields to UTF-8 before converting.
|
300
|
+
# The conversion will fail if the data cannot be transcoded, leaving the field unchanged.
|
301
|
+
#
|
302
|
+
# === Field \Converters
|
303
|
+
#
|
304
|
+
# There are three ways to use field \converters;
|
305
|
+
# these examples use built-in field converter +:integer+,
|
306
|
+
# which converts each parsed integer string to a true \Integer.
|
307
|
+
#
|
308
|
+
# Option +converters+ with a singleton parsing method:
|
309
|
+
# ary = CSV.parse_line('0,1,2', converters: :integer)
|
310
|
+
# ary # => [0, 1, 2]
|
311
|
+
#
|
312
|
+
# Option +converters+ with a new \CSV instance:
|
313
|
+
# csv = CSV.new('0,1,2', converters: :integer)
|
314
|
+
# # Field converters in effect:
|
315
|
+
# csv.converters # => [:integer]
|
316
|
+
# csv.shift # => [0, 1, 2]
|
317
|
+
#
|
318
|
+
# Method #convert adds a field converter to a \CSV instance:
|
319
|
+
# csv = CSV.new('0,1,2')
|
320
|
+
# # Add a converter.
|
321
|
+
# csv.convert(:integer)
|
322
|
+
# csv.converters # => [:integer]
|
323
|
+
# csv.shift # => [0, 1, 2]
|
324
|
+
#
|
325
|
+
# ---
|
326
|
+
#
|
327
|
+
# The built-in field \converters are in \Hash CSV::Converters.
|
328
|
+
# The \Symbol keys there are the names of the \converters:
|
329
|
+
#
|
330
|
+
# CSV::Converters.keys # => [:integer, :float, :numeric, :date, :date_time, :all]
|
331
|
+
#
|
332
|
+
# Converter +:integer+ converts each field that +Integer()+ accepts:
|
333
|
+
# data = '0,1,2,x'
|
334
|
+
# # Without the converter
|
335
|
+
# csv = CSV.parse_line(data)
|
336
|
+
# csv # => ["0", "1", "2", "x"]
|
337
|
+
# # With the converter
|
338
|
+
# csv = CSV.parse_line(data, converters: :integer)
|
339
|
+
# csv # => [0, 1, 2, "x"]
|
340
|
+
#
|
341
|
+
# Converter +:float+ converts each field that +Float()+ accepts:
|
342
|
+
# data = '1.0,3.14159,x'
|
343
|
+
# # Without the converter
|
344
|
+
# csv = CSV.parse_line(data)
|
345
|
+
# csv # => ["1.0", "3.14159", "x"]
|
346
|
+
# # With the converter
|
347
|
+
# csv = CSV.parse_line(data, converters: :float)
|
348
|
+
# csv # => [1.0, 3.14159, "x"]
|
349
|
+
#
|
350
|
+
# Converter +:numeric+ converts with both +:integer+ and +:float+..
|
351
|
+
#
|
352
|
+
# Converter +:date+ converts each field that +Date::parse()+ accepts:
|
353
|
+
# data = '2001-02-03,x'
|
354
|
+
# # Without the converter
|
355
|
+
# csv = CSV.parse_line(data)
|
356
|
+
# csv # => ["2001-02-03", "x"]
|
357
|
+
# # With the converter
|
358
|
+
# csv = CSV.parse_line(data, converters: :date)
|
359
|
+
# csv # => [#<Date: 2001-02-03 ((2451944j,0s,0n),+0s,2299161j)>, "x"]
|
360
|
+
#
|
361
|
+
# Converter +:date_time+ converts each field that +DateTime::parse() accepts:
|
362
|
+
# data = '2020-05-07T14:59:00-05:00,x'
|
363
|
+
# # Without the converter
|
364
|
+
# csv = CSV.parse_line(data)
|
365
|
+
# csv # => ["2020-05-07T14:59:00-05:00", "x"]
|
366
|
+
# # With the converter
|
367
|
+
# csv = CSV.parse_line(data, converters: :date_time)
|
368
|
+
# csv # => [#<DateTime: 2020-05-07T14:59:00-05:00 ((2458977j,71940s,0n),-18000s,2299161j)>, "x"]
|
369
|
+
#
|
370
|
+
# Converter +:numeric+ converts with both +:date_time+ and +:numeric+..
|
371
|
+
#
|
372
|
+
# As seen above, method #convert adds \converters to a \CSV instance,
|
373
|
+
# and method #converters returns an \Array of the \converters in effect:
|
374
|
+
# csv = CSV.new('0,1,2')
|
375
|
+
# csv.converters # => []
|
376
|
+
# csv.convert(:integer)
|
377
|
+
# csv.converters # => [:integer]
|
378
|
+
# csv.convert(:date)
|
379
|
+
# csv.converters # => [:integer, :date]
|
380
|
+
#
|
381
|
+
# You can add a custom field converter to \Hash CSV::Converters:
|
382
|
+
# strip_converter = proc {|field| field.strip}
|
383
|
+
# CSV::Converters[:strip] = strip_converter
|
384
|
+
# CSV::Converters.keys # => [:integer, :float, :numeric, :date, :date_time, :all, :strip]
|
385
|
+
#
|
386
|
+
# Then use it to convert fields:
|
387
|
+
# str = ' foo , 0 '
|
388
|
+
# ary = CSV.parse_line(str, converters: :strip)
|
389
|
+
# ary # => ["foo", "0"]
|
390
|
+
#
|
391
|
+
# See {Custom Converters}[#class-CSV-label-Custom+Converters].
|
392
|
+
#
|
393
|
+
# === Header \Converters
|
394
|
+
#
|
395
|
+
# Header converters operate only on headers (and not on other rows).
|
396
|
+
#
|
397
|
+
# There are three ways to use header \converters;
|
398
|
+
# these examples use built-in header converter +:dowhcase+,
|
399
|
+
# which downcases each parsed header.
|
400
|
+
#
|
401
|
+
# Option +header_converters+ with a singleton parsing method:
|
402
|
+
# str = "Name,Count\nFoo,0\n,Bar,1\nBaz,2"
|
403
|
+
# tbl = CSV.parse(str, headers: true, header_converters: :downcase)
|
404
|
+
# tbl.class # => CSV::Table
|
405
|
+
# tbl.headers # => ["name", "count"]
|
406
|
+
#
|
407
|
+
# Option +header_converters+ with a new \CSV instance:
|
408
|
+
# csv = CSV.new(str, header_converters: :downcase)
|
409
|
+
# # Header converters in effect:
|
410
|
+
# csv.header_converters # => [:downcase]
|
411
|
+
# tbl = CSV.parse(str, headers: true)
|
412
|
+
# tbl.headers # => ["Name", "Count"]
|
413
|
+
#
|
414
|
+
# Method #header_convert adds a header converter to a \CSV instance:
|
415
|
+
# csv = CSV.new(str)
|
416
|
+
# # Add a header converter.
|
417
|
+
# csv.header_convert(:downcase)
|
418
|
+
# csv.header_converters # => [:downcase]
|
419
|
+
# tbl = CSV.parse(str, headers: true)
|
420
|
+
# tbl.headers # => ["Name", "Count"]
|
421
|
+
#
|
422
|
+
# ---
|
423
|
+
#
|
424
|
+
# The built-in header \converters are in \Hash CSV::Converters.
|
425
|
+
# The \Symbol keys there are the names of the \converters:
|
426
|
+
#
|
427
|
+
# CSV::HeaderConverters.keys # => [:downcase, :symbol]
|
428
|
+
#
|
429
|
+
# Converter +:downcase+ converts each header by downcasing it:
|
430
|
+
# str = "Name,Count\nFoo,0\n,Bar,1\nBaz,2"
|
431
|
+
# tbl = CSV.parse(str, headers: true, header_converters: :downcase)
|
432
|
+
# tbl.class # => CSV::Table
|
433
|
+
# tbl.headers # => ["name", "count"]
|
434
|
+
#
|
435
|
+
# Converter +:symbol+ by making it into a \Symbol:
|
436
|
+
# str = "Name,Count\nFoo,0\n,Bar,1\nBaz,2"
|
437
|
+
# tbl = CSV.parse(str, headers: true, header_converters: :symbol)
|
438
|
+
# tbl.headers # => [:name, :count]
|
439
|
+
# Details:
|
440
|
+
# - Strips leading and trailing whitespace.
|
441
|
+
# - Downcases the header.
|
442
|
+
# - Replaces embedded spaces with underscores.
|
443
|
+
# - Removes non-word characters.
|
444
|
+
# - Makes the string into a \Symbol.
|
445
|
+
#
|
446
|
+
# You can add a custom header converter to \Hash CSV::HeaderConverters:
|
447
|
+
# strip_converter = proc {|field| field.strip}
|
448
|
+
# CSV::HeaderConverters[:strip] = strip_converter
|
449
|
+
# CSV::HeaderConverters.keys # => [:downcase, :symbol, :strip]
|
450
|
+
#
|
451
|
+
# Then use it to convert headers:
|
452
|
+
# str = " Name , Value \nfoo,0\nbar,1\nbaz,2"
|
453
|
+
# tbl = CSV.parse(str, headers: true, header_converters: :strip)
|
454
|
+
# tbl.headers # => ["Name", "Value"]
|
455
|
+
#
|
456
|
+
# See {Custom Converters}[#class-CSV-label-Custom+Converters].
|
457
|
+
#
|
458
|
+
# === Custom \Converters
|
459
|
+
#
|
460
|
+
# You can define custom \converters.
|
461
|
+
#
|
462
|
+
# The \converter is a \Proc that is called with two arguments,
|
463
|
+
# \String +field+ and CSV::FieldInfo +field_info+;
|
464
|
+
# it returns a \String that will become the field value:
|
465
|
+
# converter = proc {|field, field_info| <some_string> }
|
466
|
+
#
|
467
|
+
# To illustrate:
|
468
|
+
# converter = proc {|field, field_info| p [field, field_info]; field}
|
469
|
+
# ary = CSV.parse_line('foo,0', converters: converter)
|
470
|
+
#
|
471
|
+
# Produces:
|
472
|
+
# ["foo", #<struct CSV::FieldInfo index=0, line=1, header=nil>]
|
473
|
+
# ["0", #<struct CSV::FieldInfo index=1, line=1, header=nil>]
|
474
|
+
#
|
475
|
+
# In each of the output lines:
|
476
|
+
# - The first \Array element is the passed \String field.
|
477
|
+
# - The second is a \FieldInfo structure containing information about the field:
|
478
|
+
# - The 0-based column index.
|
479
|
+
# - The 1-based line number.
|
480
|
+
# - The header for the column, if available.
|
481
|
+
#
|
482
|
+
# If the \converter does not need +field_info+, it can be omitted:
|
483
|
+
# converter = proc {|field| ... }
|
222
484
|
#
|
223
485
|
# == CSV and Character Encodings (M17n or Multilingualization)
|
224
486
|
#
|
@@ -380,29 +642,13 @@ class CSV
|
|
380
642
|
gsub(/\s+/, "_").to_sym
|
381
643
|
}
|
382
644
|
}
|
383
|
-
|
384
|
-
#
|
385
|
-
# The options used when no overrides are given by calling code. They are:
|
386
|
-
#
|
387
|
-
# <b><tt>:col_sep</tt></b>:: <tt>","</tt>
|
388
|
-
# <b><tt>:row_sep</tt></b>:: <tt>:auto</tt>
|
389
|
-
# <b><tt>:quote_char</tt></b>:: <tt>'"'</tt>
|
390
|
-
# <b><tt>:field_size_limit</tt></b>:: +nil+
|
391
|
-
# <b><tt>:converters</tt></b>:: +nil+
|
392
|
-
# <b><tt>:unconverted_fields</tt></b>:: +nil+
|
393
|
-
# <b><tt>:headers</tt></b>:: +false+
|
394
|
-
# <b><tt>:return_headers</tt></b>:: +false+
|
395
|
-
# <b><tt>:header_converters</tt></b>:: +nil+
|
396
|
-
# <b><tt>:skip_blanks</tt></b>:: +false+
|
397
|
-
# <b><tt>:force_quotes</tt></b>:: +false+
|
398
|
-
# <b><tt>:skip_lines</tt></b>:: +nil+
|
399
|
-
# <b><tt>:liberal_parsing</tt></b>:: +false+
|
400
|
-
# <b><tt>:quote_empty</tt></b>:: +true+
|
401
|
-
#
|
645
|
+
# Default values for method options.
|
402
646
|
DEFAULT_OPTIONS = {
|
647
|
+
# For both parsing and generating.
|
403
648
|
col_sep: ",",
|
404
649
|
row_sep: :auto,
|
405
650
|
quote_char: '"',
|
651
|
+
# For parsing.
|
406
652
|
field_size_limit: nil,
|
407
653
|
converters: nil,
|
408
654
|
unconverted_fields: nil,
|
@@ -410,10 +656,18 @@ class CSV
|
|
410
656
|
return_headers: false,
|
411
657
|
header_converters: nil,
|
412
658
|
skip_blanks: false,
|
413
|
-
force_quotes: false,
|
414
659
|
skip_lines: nil,
|
415
660
|
liberal_parsing: false,
|
661
|
+
nil_value: nil,
|
662
|
+
empty_value: "",
|
663
|
+
# For generating.
|
664
|
+
write_headers: nil,
|
416
665
|
quote_empty: true,
|
666
|
+
force_quotes: false,
|
667
|
+
write_converters: nil,
|
668
|
+
write_nil_value: nil,
|
669
|
+
write_empty_value: "",
|
670
|
+
strip: false,
|
417
671
|
}.freeze
|
418
672
|
|
419
673
|
class << self
|
@@ -423,6 +677,9 @@ class CSV
|
|
423
677
|
# the same +data+ object (tested by Object#object_id()) with the same
|
424
678
|
# +options+.
|
425
679
|
#
|
680
|
+
# See {Options for Parsing}[#class-CSV-label-Options+for+Parsing]
|
681
|
+
# and {Options for Generating}[#class-CSV-label-Options+for+Generating].
|
682
|
+
#
|
426
683
|
# If a block is given, the instance is passed to the block and the return
|
427
684
|
# value becomes the return value of the block.
|
428
685
|
#
|
@@ -463,6 +720,9 @@ class CSV
|
|
463
720
|
# <tt>:out_</tt> or <tt>:output_</tt> affect only +output+. All other keys
|
464
721
|
# are assigned to both objects.
|
465
722
|
#
|
723
|
+
# See {Options for Parsing}[#class-CSV-label-Options+for+Parsing]
|
724
|
+
# and {Options for Generating}[#class-CSV-label-Options+for+Generating].
|
725
|
+
#
|
466
726
|
# The <tt>:output_row_sep</tt> +option+ defaults to
|
467
727
|
# <tt>$INPUT_RECORD_SEPARATOR</tt> (<tt>$/</tt>).
|
468
728
|
#
|
@@ -496,6 +756,8 @@ class CSV
|
|
496
756
|
# pass a +path+ and any +options+ you wish to set for the read. Each row of
|
497
757
|
# file will be passed to the provided +block+ in turn.
|
498
758
|
#
|
759
|
+
# See {Options for Parsing}[#class-CSV-label-Options+for+Parsing].
|
760
|
+
#
|
499
761
|
# The +options+ parameter can be anything CSV::new() understands. This method
|
500
762
|
# also understands an additional <tt>:encoding</tt> parameter that you can use
|
501
763
|
# to specify the Encoding of the data in the file to be read. You must provide
|
@@ -525,10 +787,11 @@ class CSV
|
|
525
787
|
# Note that a passed String *is* modified by this method. Call dup() before
|
526
788
|
# passing if you need a new String.
|
527
789
|
#
|
528
|
-
#
|
529
|
-
#
|
530
|
-
#
|
531
|
-
#
|
790
|
+
# See {Options for Generating}[#class-CSV-label-Options+for+Generating].
|
791
|
+
#
|
792
|
+
# This method has one additional option: <tt>:encoding</tt>,
|
793
|
+
# which sets the base Encoding for the output if no no +str+ is specified.
|
794
|
+
# CSV needs this hint if you plan to output non-ASCII compatible data.
|
532
795
|
#
|
533
796
|
def generate(str=nil, **options)
|
534
797
|
encoding = options[:encoding]
|
@@ -550,8 +813,9 @@ class CSV
|
|
550
813
|
# This method is a shortcut for converting a single row (Array) into a CSV
|
551
814
|
# String.
|
552
815
|
#
|
553
|
-
#
|
554
|
-
#
|
816
|
+
# See {Options for Generating}[#class-CSV-label-Options+for+Generating].
|
817
|
+
#
|
818
|
+
# This method accepts an additional option, <tt>:encoding</tt>, which sets the base
|
555
819
|
# Encoding for the output. This method will try to guess your Encoding from
|
556
820
|
# the first non-+nil+ field in +row+, if possible, but you may need to use
|
557
821
|
# this parameter as a backup plan.
|
@@ -581,8 +845,9 @@ class CSV
|
|
581
845
|
# as the primary interface for writing a CSV file.
|
582
846
|
#
|
583
847
|
# You must pass a +filename+ and may optionally add a +mode+ for Ruby's
|
584
|
-
# open().
|
585
|
-
#
|
848
|
+
# open().
|
849
|
+
#
|
850
|
+
# See {Options for Generating}[#class-CSV-label-Options+for+Generating].
|
586
851
|
#
|
587
852
|
# This method works like Ruby's open() call, in that it will pass a CSV object
|
588
853
|
# to a provided block and close it when the block terminates, or it will
|
@@ -674,8 +939,8 @@ class CSV
|
|
674
939
|
# provide a +block+ which will be called with each row of the String in turn,
|
675
940
|
# or just use the returned Array of Arrays (when no +block+ is given).
|
676
941
|
#
|
677
|
-
# You pass your +str+ to read from, and an optional +options
|
678
|
-
#
|
942
|
+
# You pass your +str+ to read from, and an optional +options+.
|
943
|
+
# See {Options for Parsing}[#class-CSV-label-Options+for+Parsing].
|
679
944
|
#
|
680
945
|
def parse(str, **options, &block)
|
681
946
|
csv = new(str, **options)
|
@@ -695,15 +960,18 @@ class CSV
|
|
695
960
|
# an Array. Note that if +line+ contains multiple rows, anything beyond the
|
696
961
|
# first row is ignored.
|
697
962
|
#
|
698
|
-
#
|
963
|
+
# See {Options for Parsing}[#class-CSV-label-Options+for+Parsing].
|
699
964
|
#
|
700
965
|
def parse_line(line, **options)
|
701
|
-
new(line, **options).
|
966
|
+
new(line, **options).each.first
|
702
967
|
end
|
703
968
|
|
704
969
|
#
|
705
970
|
# Use to slurp a CSV file into an Array of Arrays. Pass the +path+ to the
|
706
|
-
# file and
|
971
|
+
# file and +options+.
|
972
|
+
# See {Options for Parsing}[#class-CSV-label-Options+for+Parsing].
|
973
|
+
#
|
974
|
+
# This method also understands
|
707
975
|
# an additional <tt>:encoding</tt> parameter that you can use to specify the
|
708
976
|
# Encoding of the data in the file to be read. You must provide this unless
|
709
977
|
# your data is in Encoding::default_external(). CSV will use this to determine
|
@@ -728,6 +996,7 @@ class CSV
|
|
728
996
|
# converters: :numeric,
|
729
997
|
# header_converters: :symbol }.merge(options) )
|
730
998
|
#
|
999
|
+
# See {Options for Parsing}[#class-CSV-label-Options+for+Parsing].
|
731
1000
|
def table(path, **options)
|
732
1001
|
default_options = {
|
733
1002
|
headers: true,
|
@@ -750,171 +1019,8 @@ class CSV
|
|
750
1019
|
# reading). If you want it at the end (for writing), use CSV::generate().
|
751
1020
|
# If you want any other positioning, pass a preset StringIO object instead.
|
752
1021
|
#
|
753
|
-
#
|
754
|
-
#
|
755
|
-
#
|
756
|
-
# <b><tt>:col_sep</tt></b>:: The String placed between each field.
|
757
|
-
# This String will be transcoded into
|
758
|
-
# the data's Encoding before parsing.
|
759
|
-
# <b><tt>:row_sep</tt></b>:: The String appended to the end of each
|
760
|
-
# row. This can be set to the special
|
761
|
-
# <tt>:auto</tt> setting, which requests
|
762
|
-
# that CSV automatically discover this
|
763
|
-
# from the data. Auto-discovery reads
|
764
|
-
# ahead in the data looking for the next
|
765
|
-
# <tt>"\r\n"</tt>, <tt>"\n"</tt>, or
|
766
|
-
# <tt>"\r"</tt> sequence. A sequence
|
767
|
-
# will be selected even if it occurs in
|
768
|
-
# a quoted field, assuming that you
|
769
|
-
# would have the same line endings
|
770
|
-
# there. If none of those sequences is
|
771
|
-
# found, +data+ is <tt>ARGF</tt>,
|
772
|
-
# <tt>STDIN</tt>, <tt>STDOUT</tt>, or
|
773
|
-
# <tt>STDERR</tt>, or the stream is only
|
774
|
-
# available for output, the default
|
775
|
-
# <tt>$INPUT_RECORD_SEPARATOR</tt>
|
776
|
-
# (<tt>$/</tt>) is used. Obviously,
|
777
|
-
# discovery takes a little time. Set
|
778
|
-
# manually if speed is important. Also
|
779
|
-
# note that IO objects should be opened
|
780
|
-
# in binary mode on Windows if this
|
781
|
-
# feature will be used as the
|
782
|
-
# line-ending translation can cause
|
783
|
-
# problems with resetting the document
|
784
|
-
# position to where it was before the
|
785
|
-
# read ahead. This String will be
|
786
|
-
# transcoded into the data's Encoding
|
787
|
-
# before parsing.
|
788
|
-
# <b><tt>:quote_char</tt></b>:: The character used to quote fields.
|
789
|
-
# This has to be a single character
|
790
|
-
# String. This is useful for
|
791
|
-
# application that incorrectly use
|
792
|
-
# <tt>'</tt> as the quote character
|
793
|
-
# instead of the correct <tt>"</tt>.
|
794
|
-
# CSV will always consider a double
|
795
|
-
# sequence of this character to be an
|
796
|
-
# escaped quote. This String will be
|
797
|
-
# transcoded into the data's Encoding
|
798
|
-
# before parsing.
|
799
|
-
# <b><tt>:field_size_limit</tt></b>:: This is a maximum size CSV will read
|
800
|
-
# ahead looking for the closing quote
|
801
|
-
# for a field. (In truth, it reads to
|
802
|
-
# the first line ending beyond this
|
803
|
-
# size.) If a quote cannot be found
|
804
|
-
# within the limit CSV will raise a
|
805
|
-
# MalformedCSVError, assuming the data
|
806
|
-
# is faulty. You can use this limit to
|
807
|
-
# prevent what are effectively DoS
|
808
|
-
# attacks on the parser. However, this
|
809
|
-
# limit can cause a legitimate parse to
|
810
|
-
# fail and thus is set to +nil+, or off,
|
811
|
-
# by default.
|
812
|
-
# <b><tt>:converters</tt></b>:: An Array of names from the Converters
|
813
|
-
# Hash and/or lambdas that handle custom
|
814
|
-
# conversion. A single converter
|
815
|
-
# doesn't have to be in an Array. All
|
816
|
-
# built-in converters try to transcode
|
817
|
-
# fields to UTF-8 before converting.
|
818
|
-
# The conversion will fail if the data
|
819
|
-
# cannot be transcoded, leaving the
|
820
|
-
# field unchanged.
|
821
|
-
# <b><tt>:unconverted_fields</tt></b>:: If set to +true+, an
|
822
|
-
# unconverted_fields() method will be
|
823
|
-
# added to all returned rows (Array or
|
824
|
-
# CSV::Row) that will return the fields
|
825
|
-
# as they were before conversion. Note
|
826
|
-
# that <tt>:headers</tt> supplied by
|
827
|
-
# Array or String were not fields of the
|
828
|
-
# document and thus will have an empty
|
829
|
-
# Array attached.
|
830
|
-
# <b><tt>:headers</tt></b>:: If set to <tt>:first_row</tt> or
|
831
|
-
# +true+, the initial row of the CSV
|
832
|
-
# file will be treated as a row of
|
833
|
-
# headers. If set to an Array, the
|
834
|
-
# contents will be used as the headers.
|
835
|
-
# If set to a String, the String is run
|
836
|
-
# through a call of CSV::parse_line()
|
837
|
-
# with the same <tt>:col_sep</tt>,
|
838
|
-
# <tt>:row_sep</tt>, and
|
839
|
-
# <tt>:quote_char</tt> as this instance
|
840
|
-
# to produce an Array of headers. This
|
841
|
-
# setting causes CSV#shift() to return
|
842
|
-
# rows as CSV::Row objects instead of
|
843
|
-
# Arrays and CSV#read() to return
|
844
|
-
# CSV::Table objects instead of an Array
|
845
|
-
# of Arrays.
|
846
|
-
# <b><tt>:return_headers</tt></b>:: When +false+, header rows are silently
|
847
|
-
# swallowed. If set to +true+, header
|
848
|
-
# rows are returned in a CSV::Row object
|
849
|
-
# with identical headers and
|
850
|
-
# fields (save that the fields do not go
|
851
|
-
# through the converters).
|
852
|
-
# <b><tt>:write_headers</tt></b>:: When +true+ and <tt>:headers</tt> is
|
853
|
-
# set, a header row will be added to the
|
854
|
-
# output.
|
855
|
-
# <b><tt>:header_converters</tt></b>:: Identical in functionality to
|
856
|
-
# <tt>:converters</tt> save that the
|
857
|
-
# conversions are only made to header
|
858
|
-
# rows. All built-in converters try to
|
859
|
-
# transcode headers to UTF-8 before
|
860
|
-
# converting. The conversion will fail
|
861
|
-
# if the data cannot be transcoded,
|
862
|
-
# leaving the header unchanged.
|
863
|
-
# <b><tt>:skip_blanks</tt></b>:: When setting a +true+ value, CSV will
|
864
|
-
# skip over any empty rows. Note that
|
865
|
-
# this setting will not skip rows that
|
866
|
-
# contain column separators, even if
|
867
|
-
# the rows contain no actual data. If
|
868
|
-
# you want to skip rows that contain
|
869
|
-
# separators but no content, consider
|
870
|
-
# using <tt>:skip_lines</tt>, or
|
871
|
-
# inspecting fields.compact.empty? on
|
872
|
-
# each row.
|
873
|
-
# <b><tt>:force_quotes</tt></b>:: When setting a +true+ value, CSV will
|
874
|
-
# quote all CSV fields it creates.
|
875
|
-
# <b><tt>:skip_lines</tt></b>:: When setting an object responding to
|
876
|
-
# <tt>match</tt>, every line matching
|
877
|
-
# it is considered a comment and ignored
|
878
|
-
# during parsing. When set to a String,
|
879
|
-
# it is first converted to a Regexp.
|
880
|
-
# When set to +nil+ no line is considered
|
881
|
-
# a comment. If the passed object does
|
882
|
-
# not respond to <tt>match</tt>,
|
883
|
-
# <tt>ArgumentError</tt> is thrown.
|
884
|
-
# <b><tt>:liberal_parsing</tt></b>:: When setting a +true+ value, CSV will
|
885
|
-
# attempt to parse input not conformant
|
886
|
-
# with RFC 4180, such as double quotes
|
887
|
-
# in unquoted fields.
|
888
|
-
# <b><tt>:nil_value</tt></b>:: When set an object, any values of an
|
889
|
-
# empty field is replaced by the set
|
890
|
-
# object, not nil.
|
891
|
-
# <b><tt>:empty_value</tt></b>:: When setting an object, any values of a
|
892
|
-
# blank string field is replaced by
|
893
|
-
# the set object.
|
894
|
-
# <b><tt>:quote_empty</tt></b>:: When setting a +true+ value, CSV will
|
895
|
-
# quote empty values with double quotes.
|
896
|
-
# When +false+, CSV will emit an
|
897
|
-
# empty string for an empty field value.
|
898
|
-
# <b><tt>:write_converters</tt></b>:: Converts values on each line with the
|
899
|
-
# specified <tt>Proc</tt> object(s),
|
900
|
-
# which receive a <tt>String</tt> value
|
901
|
-
# and return a <tt>String</tt> or +nil+
|
902
|
-
# value.
|
903
|
-
# When an array is specified, each
|
904
|
-
# converter will be applied in order.
|
905
|
-
# <b><tt>:write_nil_value</tt></b>:: When a <tt>String</tt> value, +nil+
|
906
|
-
# value(s) on each line will be replaced
|
907
|
-
# with the specified value.
|
908
|
-
# <b><tt>:write_empty_value</tt></b>:: When a <tt>String</tt> or +nil+ value,
|
909
|
-
# empty value(s) on each line will be
|
910
|
-
# replaced with the specified value.
|
911
|
-
# <b><tt>:strip</tt></b>:: When setting a +true+ value, CSV will
|
912
|
-
# strip " \t\f\v" around the values.
|
913
|
-
# If you specify a string instead of
|
914
|
-
# +true+, CSV will strip string. The
|
915
|
-
# length of the string must be 1.
|
916
|
-
#
|
917
|
-
# See CSV::DEFAULT_OPTIONS for the default settings.
|
1022
|
+
# See {Options for Parsing}[#class-CSV-label-Options+for+Parsing]
|
1023
|
+
# and {Options for Generating}[#class-CSV-label-Options+for+Generating].
|
918
1024
|
#
|
919
1025
|
# Options cannot be overridden in the instance methods for performance reasons,
|
920
1026
|
# so be sure to set what you want here.
|
data/lib/csv/fields_converter.rb
CHANGED
@@ -50,7 +50,7 @@ class CSV
|
|
50
50
|
fields.collect.with_index do |field, index|
|
51
51
|
if field.nil?
|
52
52
|
field = @nil_value
|
53
|
-
elsif field.empty?
|
53
|
+
elsif field.is_a?(String) and field.empty?
|
54
54
|
field = @empty_value unless @empty_value_is_empty_string
|
55
55
|
end
|
56
56
|
@converters.each do |converter|
|
data/lib/csv/parser.rb
CHANGED
data/lib/csv/version.rb
CHANGED
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
|
+
version: 3.1.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- James Edward Gray II
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2020-05-
|
12
|
+
date: 2020-05-17 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: bundler
|