csv 3.1.3 → 3.1.4
Sign up to get free protection for your applications and to get access to all the features.
- 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
|