PageRenderTime 57ms CodeModel.GetById 18ms RepoModel.GetById 1ms app.codeStats 0ms

/lib/csv.rb

https://github.com/diabolo/ruby
Ruby | 2334 lines | 960 code | 170 blank | 1204 comment | 150 complexity | 194ee61bdd3ca1245c016b26fb09ddaf MD5 | raw file
Possible License(s): GPL-2.0, BSD-3-Clause

Large files files are truncated, but you can click here to view the full file

  1. # encoding: US-ASCII
  2. # = csv.rb -- CSV Reading and Writing
  3. #
  4. # Created by James Edward Gray II on 2005-10-31.
  5. # Copyright 2005 James Edward Gray II. You can redistribute or modify this code
  6. # under the terms of Ruby's license.
  7. #
  8. # See CSV for documentation.
  9. #
  10. # == Description
  11. #
  12. # Welcome to the new and improved CSV.
  13. #
  14. # This version of the CSV library began its life as FasterCSV. FasterCSV was
  15. # intended as a replacement to Ruby's then standard CSV library. It was
  16. # designed to address concerns users of that library had and it had three
  17. # primary goals:
  18. #
  19. # 1. Be significantly faster than CSV while remaining a pure Ruby library.
  20. # 2. Use a smaller and easier to maintain code base. (FasterCSV eventually
  21. # grew larger, was also but considerably richer in features. The parsing
  22. # core remains quite small.)
  23. # 3. Improve on the CSV interface.
  24. #
  25. # Obviously, the last one is subjective. I did try to defer to the original
  26. # interface whenever I didn't have a compelling reason to change it though, so
  27. # hopefully this won't be too radically different.
  28. #
  29. # We must have met our goals because FasterCSV was renamed to CSV and replaced
  30. # the original library.
  31. #
  32. # == What's Different From the Old CSV?
  33. #
  34. # I'm sure I'll miss something, but I'll try to mention most of the major
  35. # differences I am aware of, to help others quickly get up to speed:
  36. #
  37. # === CSV Parsing
  38. #
  39. # * This parser is m17n aware. See CSV for full details.
  40. # * This library has a stricter parser and will throw MalformedCSVErrors on
  41. # problematic data.
  42. # * This library has a less liberal idea of a line ending than CSV. What you
  43. # set as the <tt>:row_sep</tt> is law. It can auto-detect your line endings
  44. # though.
  45. # * The old library returned empty lines as <tt>[nil]</tt>. This library calls
  46. # them <tt>[]</tt>.
  47. # * This library has a much faster parser.
  48. #
  49. # === Interface
  50. #
  51. # * CSV now uses Hash-style parameters to set options.
  52. # * CSV no longer has generate_row() or parse_row().
  53. # * The old CSV's Reader and Writer classes have been dropped.
  54. # * CSV::open() is now more like Ruby's open().
  55. # * CSV objects now support most standard IO methods.
  56. # * CSV now has a new() method used to wrap objects like String and IO for
  57. # reading and writing.
  58. # * CSV::generate() is different from the old method.
  59. # * CSV no longer supports partial reads. It works line-by-line.
  60. # * CSV no longer allows the instance methods to override the separators for
  61. # performance reasons. They must be set in the constructor.
  62. #
  63. # If you use this library and find yourself missing any functionality I have
  64. # trimmed, please {let me know}[mailto:james@grayproductions.net].
  65. #
  66. # == Documentation
  67. #
  68. # See CSV for documentation.
  69. #
  70. # == What is CSV, really?
  71. #
  72. # CSV maintains a pretty strict definition of CSV taken directly from
  73. # {the RFC}[http://www.ietf.org/rfc/rfc4180.txt]. I relax the rules in only one
  74. # place and that is to make using this library easier. CSV will parse all valid
  75. # CSV.
  76. #
  77. # What you don't want to do is feed CSV invalid data. Because of the way the
  78. # CSV format works, it's common for a parser to need to read until the end of
  79. # the file to be sure a field is invalid. This eats a lot of time and memory.
  80. #
  81. # Luckily, when working with invalid CSV, Ruby's built-in methods will almost
  82. # always be superior in every way. For example, parsing non-quoted fields is as
  83. # easy as:
  84. #
  85. # data.split(",")
  86. #
  87. # == Questions and/or Comments
  88. #
  89. # Feel free to email {James Edward Gray II}[mailto:james@grayproductions.net]
  90. # with any questions.
  91. require "forwardable"
  92. require "English"
  93. require "date"
  94. require "stringio"
  95. #
  96. # This class provides a complete interface to CSV files and data. It offers
  97. # tools to enable you to read and write to and from Strings or IO objects, as
  98. # needed.
  99. #
  100. # == Reading
  101. #
  102. # === From a File
  103. #
  104. # ==== A Line at a Time
  105. #
  106. # CSV.foreach("path/to/file.csv") do |row|
  107. # # use row here...
  108. # end
  109. #
  110. # ==== All at Once
  111. #
  112. # arr_of_arrs = CSV.read("path/to/file.csv")
  113. #
  114. # === From a String
  115. #
  116. # ==== A Line at a Time
  117. #
  118. # CSV.parse("CSV,data,String") do |row|
  119. # # use row here...
  120. # end
  121. #
  122. # ==== All at Once
  123. #
  124. # arr_of_arrs = CSV.parse("CSV,data,String")
  125. #
  126. # == Writing
  127. #
  128. # === To a File
  129. #
  130. # CSV.open("path/to/file.csv", "wb") do |csv|
  131. # csv << ["row", "of", "CSV", "data"]
  132. # csv << ["another", "row"]
  133. # # ...
  134. # end
  135. #
  136. # === To a String
  137. #
  138. # csv_string = CSV.generate do |csv|
  139. # csv << ["row", "of", "CSV", "data"]
  140. # csv << ["another", "row"]
  141. # # ...
  142. # end
  143. #
  144. # == Convert a Single Line
  145. #
  146. # csv_string = ["CSV", "data"].to_csv # to CSV
  147. # csv_array = "CSV,String".parse_csv # from CSV
  148. #
  149. # == Shortcut Interface
  150. #
  151. # CSV { |csv_out| csv_out << %w{my data here} } # to $stdout
  152. # CSV(csv = "") { |csv_str| csv_str << %w{my data here} } # to a String
  153. # CSV($stderr) { |csv_err| csv_err << %w{my data here} } # to $stderr
  154. # CSV($stdin) { |csv_in| csv_in.each { |row| p row } } # from $stdin
  155. #
  156. # == Advanced Usage
  157. #
  158. # === Wrap an IO Object
  159. #
  160. # csv = CSV.new(io, options)
  161. # # ... read (with gets() or each()) from and write (with <<) to csv here ...
  162. #
  163. # == CSV and Character Encodings (M17n or Multilingualization)
  164. #
  165. # This new CSV parser is m17n savvy. The parser works in the Encoding of the IO
  166. # or String object being read from or written to. Your data is never transcoded
  167. # (unless you ask Ruby to transcode it for you) and will literally be parsed in
  168. # the Encoding it is in. Thus CSV will return Arrays or Rows of Strings in the
  169. # Encoding of your data. This is accomplished by transcoding the parser itself
  170. # into your Encoding.
  171. #
  172. # Some transcoding must take place, of course, to accomplish this multiencoding
  173. # support. For example, <tt>:col_sep</tt>, <tt>:row_sep</tt>, and
  174. # <tt>:quote_char</tt> must be transcoded to match your data. Hopefully this
  175. # makes the entire process feel transparent, since CSV's defaults should just
  176. # magically work for you data. However, you can set these values manually in
  177. # the target Encoding to avoid the translation.
  178. #
  179. # It's also important to note that while all of CSV's core parser is now
  180. # Encoding agnostic, some features are not. For example, the built-in
  181. # converters will try to transcode data to UTF-8 before making conversions.
  182. # Again, you can provide custom converters that are aware of your Encodings to
  183. # avoid this translation. It's just too hard for me to support native
  184. # conversions in all of Ruby's Encodings.
  185. #
  186. # Anyway, the practical side of this is simple: make sure IO and String objects
  187. # passed into CSV have the proper Encoding set and everything should just work.
  188. # CSV methods that allow you to open IO objects (CSV::foreach(), CSV::open(),
  189. # CSV::read(), and CSV::readlines()) do allow you to specify the Encoding.
  190. #
  191. # One minor exception comes when generating CSV into a String with an Encoding
  192. # that is not ASCII compatible. There's no existing data for CSV to use to
  193. # prepare itself and thus you will probably need to manually specify the desired
  194. # Encoding for most of those cases. It will try to guess using the fields in a
  195. # row of output though, when using CSV::generate_line() or Array#to_csv().
  196. #
  197. # I try to point out any other Encoding issues in the documentation of methods
  198. # as they come up.
  199. #
  200. # This has been tested to the best of my ability with all non-"dummy" Encodings
  201. # Ruby ships with. However, it is brave new code and may have some bugs.
  202. # Please feel free to {report}[mailto:james@grayproductions.net] any issues you
  203. # find with it.
  204. #
  205. class CSV
  206. # The version of the installed library.
  207. VERSION = "2.4.7".freeze
  208. #
  209. # A CSV::Row is part Array and part Hash. It retains an order for the fields
  210. # and allows duplicates just as an Array would, but also allows you to access
  211. # fields by name just as you could if they were in a Hash.
  212. #
  213. # All rows returned by CSV will be constructed from this class, if header row
  214. # processing is activated.
  215. #
  216. class Row
  217. #
  218. # Construct a new CSV::Row from +headers+ and +fields+, which are expected
  219. # to be Arrays. If one Array is shorter than the other, it will be padded
  220. # with +nil+ objects.
  221. #
  222. # The optional +header_row+ parameter can be set to +true+ to indicate, via
  223. # CSV::Row.header_row?() and CSV::Row.field_row?(), that this is a header
  224. # row. Otherwise, the row is assumes to be a field row.
  225. #
  226. # A CSV::Row object supports the following Array methods through delegation:
  227. #
  228. # * empty?()
  229. # * length()
  230. # * size()
  231. #
  232. def initialize(headers, fields, header_row = false)
  233. @header_row = header_row
  234. # handle extra headers or fields
  235. @row = if headers.size > fields.size
  236. headers.zip(fields)
  237. else
  238. fields.zip(headers).map { |pair| pair.reverse }
  239. end
  240. end
  241. # Internal data format used to compare equality.
  242. attr_reader :row
  243. protected :row
  244. ### Array Delegation ###
  245. extend Forwardable
  246. def_delegators :@row, :empty?, :length, :size
  247. # Returns +true+ if this is a header row.
  248. def header_row?
  249. @header_row
  250. end
  251. # Returns +true+ if this is a field row.
  252. def field_row?
  253. not header_row?
  254. end
  255. # Returns the headers of this row.
  256. def headers
  257. @row.map { |pair| pair.first }
  258. end
  259. #
  260. # :call-seq:
  261. # field( header )
  262. # field( header, offset )
  263. # field( index )
  264. #
  265. # This method will fetch the field value by +header+ or +index+. If a field
  266. # is not found, +nil+ is returned.
  267. #
  268. # When provided, +offset+ ensures that a header match occurrs on or later
  269. # than the +offset+ index. You can use this to find duplicate headers,
  270. # without resorting to hard-coding exact indices.
  271. #
  272. def field(header_or_index, minimum_index = 0)
  273. # locate the pair
  274. finder = header_or_index.is_a?(Integer) ? :[] : :assoc
  275. pair = @row[minimum_index..-1].send(finder, header_or_index)
  276. # return the field if we have a pair
  277. pair.nil? ? nil : pair.last
  278. end
  279. alias_method :[], :field
  280. #
  281. # :call-seq:
  282. # []=( header, value )
  283. # []=( header, offset, value )
  284. # []=( index, value )
  285. #
  286. # Looks up the field by the semantics described in CSV::Row.field() and
  287. # assigns the +value+.
  288. #
  289. # Assigning past the end of the row with an index will set all pairs between
  290. # to <tt>[nil, nil]</tt>. Assigning to an unused header appends the new
  291. # pair.
  292. #
  293. def []=(*args)
  294. value = args.pop
  295. if args.first.is_a? Integer
  296. if @row[args.first].nil? # extending past the end with index
  297. @row[args.first] = [nil, value]
  298. @row.map! { |pair| pair.nil? ? [nil, nil] : pair }
  299. else # normal index assignment
  300. @row[args.first][1] = value
  301. end
  302. else
  303. index = index(*args)
  304. if index.nil? # appending a field
  305. self << [args.first, value]
  306. else # normal header assignment
  307. @row[index][1] = value
  308. end
  309. end
  310. end
  311. #
  312. # :call-seq:
  313. # <<( field )
  314. # <<( header_and_field_array )
  315. # <<( header_and_field_hash )
  316. #
  317. # If a two-element Array is provided, it is assumed to be a header and field
  318. # and the pair is appended. A Hash works the same way with the key being
  319. # the header and the value being the field. Anything else is assumed to be
  320. # a lone field which is appended with a +nil+ header.
  321. #
  322. # This method returns the row for chaining.
  323. #
  324. def <<(arg)
  325. if arg.is_a?(Array) and arg.size == 2 # appending a header and name
  326. @row << arg
  327. elsif arg.is_a?(Hash) # append header and name pairs
  328. arg.each { |pair| @row << pair }
  329. else # append field value
  330. @row << [nil, arg]
  331. end
  332. self # for chaining
  333. end
  334. #
  335. # A shortcut for appending multiple fields. Equivalent to:
  336. #
  337. # args.each { |arg| csv_row << arg }
  338. #
  339. # This method returns the row for chaining.
  340. #
  341. def push(*args)
  342. args.each { |arg| self << arg }
  343. self # for chaining
  344. end
  345. #
  346. # :call-seq:
  347. # delete( header )
  348. # delete( header, offset )
  349. # delete( index )
  350. #
  351. # Used to remove a pair from the row by +header+ or +index+. The pair is
  352. # located as described in CSV::Row.field(). The deleted pair is returned,
  353. # or +nil+ if a pair could not be found.
  354. #
  355. def delete(header_or_index, minimum_index = 0)
  356. if header_or_index.is_a? Integer # by index
  357. @row.delete_at(header_or_index)
  358. elsif i = index(header_or_index, minimum_index) # by header
  359. @row.delete_at(i)
  360. else
  361. [ ]
  362. end
  363. end
  364. #
  365. # The provided +block+ is passed a header and field for each pair in the row
  366. # and expected to return +true+ or +false+, depending on whether the pair
  367. # should be deleted.
  368. #
  369. # This method returns the row for chaining.
  370. #
  371. def delete_if(&block)
  372. @row.delete_if(&block)
  373. self # for chaining
  374. end
  375. #
  376. # This method accepts any number of arguments which can be headers, indices,
  377. # Ranges of either, or two-element Arrays containing a header and offset.
  378. # Each argument will be replaced with a field lookup as described in
  379. # CSV::Row.field().
  380. #
  381. # If called with no arguments, all fields are returned.
  382. #
  383. def fields(*headers_and_or_indices)
  384. if headers_and_or_indices.empty? # return all fields--no arguments
  385. @row.map { |pair| pair.last }
  386. else # or work like values_at()
  387. headers_and_or_indices.inject(Array.new) do |all, h_or_i|
  388. all + if h_or_i.is_a? Range
  389. index_begin = h_or_i.begin.is_a?(Integer) ? h_or_i.begin :
  390. index(h_or_i.begin)
  391. index_end = h_or_i.end.is_a?(Integer) ? h_or_i.end :
  392. index(h_or_i.end)
  393. new_range = h_or_i.exclude_end? ? (index_begin...index_end) :
  394. (index_begin..index_end)
  395. fields.values_at(new_range)
  396. else
  397. [field(*Array(h_or_i))]
  398. end
  399. end
  400. end
  401. end
  402. alias_method :values_at, :fields
  403. #
  404. # :call-seq:
  405. # index( header )
  406. # index( header, offset )
  407. #
  408. # This method will return the index of a field with the provided +header+.
  409. # The +offset+ can be used to locate duplicate header names, as described in
  410. # CSV::Row.field().
  411. #
  412. def index(header, minimum_index = 0)
  413. # find the pair
  414. index = headers[minimum_index..-1].index(header)
  415. # return the index at the right offset, if we found one
  416. index.nil? ? nil : index + minimum_index
  417. end
  418. # Returns +true+ if +name+ is a header for this row, and +false+ otherwise.
  419. def header?(name)
  420. headers.include? name
  421. end
  422. alias_method :include?, :header?
  423. #
  424. # Returns +true+ if +data+ matches a field in this row, and +false+
  425. # otherwise.
  426. #
  427. def field?(data)
  428. fields.include? data
  429. end
  430. include Enumerable
  431. #
  432. # Yields each pair of the row as header and field tuples (much like
  433. # iterating over a Hash).
  434. #
  435. # Support for Enumerable.
  436. #
  437. # This method returns the row for chaining.
  438. #
  439. def each(&block)
  440. @row.each(&block)
  441. self # for chaining
  442. end
  443. #
  444. # Returns +true+ if this row contains the same headers and fields in the
  445. # same order as +other+.
  446. #
  447. def ==(other)
  448. @row == other.row
  449. end
  450. #
  451. # Collapses the row into a simple Hash. Be warning that this discards field
  452. # order and clobbers duplicate fields.
  453. #
  454. def to_hash
  455. # flatten just one level of the internal Array
  456. Hash[*@row.inject(Array.new) { |ary, pair| ary.push(*pair) }]
  457. end
  458. #
  459. # Returns the row as a CSV String. Headers are not used. Equivalent to:
  460. #
  461. # csv_row.fields.to_csv( options )
  462. #
  463. def to_csv(options = Hash.new)
  464. fields.to_csv(options)
  465. end
  466. alias_method :to_s, :to_csv
  467. # A summary of fields, by header, in an ASCII compatible String.
  468. def inspect
  469. str = ["#<", self.class.to_s]
  470. each do |header, field|
  471. str << " " << (header.is_a?(Symbol) ? header.to_s : header.inspect) <<
  472. ":" << field.inspect
  473. end
  474. str << ">"
  475. begin
  476. str.join
  477. rescue # any encoding error
  478. str.map do |s|
  479. e = Encoding::Converter.asciicompat_encoding(s.encoding)
  480. e ? s.encode(e) : s.force_encoding("ASCII-8BIT")
  481. end.join
  482. end
  483. end
  484. end
  485. #
  486. # A CSV::Table is a two-dimensional data structure for representing CSV
  487. # documents. Tables allow you to work with the data by row or column,
  488. # manipulate the data, and even convert the results back to CSV, if needed.
  489. #
  490. # All tables returned by CSV will be constructed from this class, if header
  491. # row processing is activated.
  492. #
  493. class Table
  494. #
  495. # Construct a new CSV::Table from +array_of_rows+, which are expected
  496. # to be CSV::Row objects. All rows are assumed to have the same headers.
  497. #
  498. # A CSV::Table object supports the following Array methods through
  499. # delegation:
  500. #
  501. # * empty?()
  502. # * length()
  503. # * size()
  504. #
  505. def initialize(array_of_rows)
  506. @table = array_of_rows
  507. @mode = :col_or_row
  508. end
  509. # The current access mode for indexing and iteration.
  510. attr_reader :mode
  511. # Internal data format used to compare equality.
  512. attr_reader :table
  513. protected :table
  514. ### Array Delegation ###
  515. extend Forwardable
  516. def_delegators :@table, :empty?, :length, :size
  517. #
  518. # Returns a duplicate table object, in column mode. This is handy for
  519. # chaining in a single call without changing the table mode, but be aware
  520. # that this method can consume a fair amount of memory for bigger data sets.
  521. #
  522. # This method returns the duplicate table for chaining. Don't chain
  523. # destructive methods (like []=()) this way though, since you are working
  524. # with a duplicate.
  525. #
  526. def by_col
  527. self.class.new(@table.dup).by_col!
  528. end
  529. #
  530. # Switches the mode of this table to column mode. All calls to indexing and
  531. # iteration methods will work with columns until the mode is changed again.
  532. #
  533. # This method returns the table and is safe to chain.
  534. #
  535. def by_col!
  536. @mode = :col
  537. self
  538. end
  539. #
  540. # Returns a duplicate table object, in mixed mode. This is handy for
  541. # chaining in a single call without changing the table mode, but be aware
  542. # that this method can consume a fair amount of memory for bigger data sets.
  543. #
  544. # This method returns the duplicate table for chaining. Don't chain
  545. # destructive methods (like []=()) this way though, since you are working
  546. # with a duplicate.
  547. #
  548. def by_col_or_row
  549. self.class.new(@table.dup).by_col_or_row!
  550. end
  551. #
  552. # Switches the mode of this table to mixed mode. All calls to indexing and
  553. # iteration methods will use the default intelligent indexing system until
  554. # the mode is changed again. In mixed mode an index is assumed to be a row
  555. # reference while anything else is assumed to be column access by headers.
  556. #
  557. # This method returns the table and is safe to chain.
  558. #
  559. def by_col_or_row!
  560. @mode = :col_or_row
  561. self
  562. end
  563. #
  564. # Returns a duplicate table object, in row mode. This is handy for chaining
  565. # in a single call without changing the table mode, but be aware that this
  566. # method can consume a fair amount of memory for bigger data sets.
  567. #
  568. # This method returns the duplicate table for chaining. Don't chain
  569. # destructive methods (like []=()) this way though, since you are working
  570. # with a duplicate.
  571. #
  572. def by_row
  573. self.class.new(@table.dup).by_row!
  574. end
  575. #
  576. # Switches the mode of this table to row mode. All calls to indexing and
  577. # iteration methods will work with rows until the mode is changed again.
  578. #
  579. # This method returns the table and is safe to chain.
  580. #
  581. def by_row!
  582. @mode = :row
  583. self
  584. end
  585. #
  586. # Returns the headers for the first row of this table (assumed to match all
  587. # other rows). An empty Array is returned for empty tables.
  588. #
  589. def headers
  590. if @table.empty?
  591. Array.new
  592. else
  593. @table.first.headers
  594. end
  595. end
  596. #
  597. # In the default mixed mode, this method returns rows for index access and
  598. # columns for header access. You can force the index association by first
  599. # calling by_col!() or by_row!().
  600. #
  601. # Columns are returned as an Array of values. Altering that Array has no
  602. # effect on the table.
  603. #
  604. def [](index_or_header)
  605. if @mode == :row or # by index
  606. (@mode == :col_or_row and index_or_header.is_a? Integer)
  607. @table[index_or_header]
  608. else # by header
  609. @table.map { |row| row[index_or_header] }
  610. end
  611. end
  612. #
  613. # In the default mixed mode, this method assigns rows for index access and
  614. # columns for header access. You can force the index association by first
  615. # calling by_col!() or by_row!().
  616. #
  617. # Rows may be set to an Array of values (which will inherit the table's
  618. # headers()) or a CSV::Row.
  619. #
  620. # Columns may be set to a single value, which is copied to each row of the
  621. # column, or an Array of values. Arrays of values are assigned to rows top
  622. # to bottom in row major order. Excess values are ignored and if the Array
  623. # does not have a value for each row the extra rows will receive a +nil+.
  624. #
  625. # Assigning to an existing column or row clobbers the data. Assigning to
  626. # new columns creates them at the right end of the table.
  627. #
  628. def []=(index_or_header, value)
  629. if @mode == :row or # by index
  630. (@mode == :col_or_row and index_or_header.is_a? Integer)
  631. if value.is_a? Array
  632. @table[index_or_header] = Row.new(headers, value)
  633. else
  634. @table[index_or_header] = value
  635. end
  636. else # set column
  637. if value.is_a? Array # multiple values
  638. @table.each_with_index do |row, i|
  639. if row.header_row?
  640. row[index_or_header] = index_or_header
  641. else
  642. row[index_or_header] = value[i]
  643. end
  644. end
  645. else # repeated value
  646. @table.each do |row|
  647. if row.header_row?
  648. row[index_or_header] = index_or_header
  649. else
  650. row[index_or_header] = value
  651. end
  652. end
  653. end
  654. end
  655. end
  656. #
  657. # The mixed mode default is to treat a list of indices as row access,
  658. # returning the rows indicated. Anything else is considered columnar
  659. # access. For columnar access, the return set has an Array for each row
  660. # with the values indicated by the headers in each Array. You can force
  661. # column or row mode using by_col!() or by_row!().
  662. #
  663. # You cannot mix column and row access.
  664. #
  665. def values_at(*indices_or_headers)
  666. if @mode == :row or # by indices
  667. ( @mode == :col_or_row and indices_or_headers.all? do |index|
  668. index.is_a?(Integer) or
  669. ( index.is_a?(Range) and
  670. index.first.is_a?(Integer) and
  671. index.last.is_a?(Integer) )
  672. end )
  673. @table.values_at(*indices_or_headers)
  674. else # by headers
  675. @table.map { |row| row.values_at(*indices_or_headers) }
  676. end
  677. end
  678. #
  679. # Adds a new row to the bottom end of this table. You can provide an Array,
  680. # which will be converted to a CSV::Row (inheriting the table's headers()),
  681. # or a CSV::Row.
  682. #
  683. # This method returns the table for chaining.
  684. #
  685. def <<(row_or_array)
  686. if row_or_array.is_a? Array # append Array
  687. @table << Row.new(headers, row_or_array)
  688. else # append Row
  689. @table << row_or_array
  690. end
  691. self # for chaining
  692. end
  693. #
  694. # A shortcut for appending multiple rows. Equivalent to:
  695. #
  696. # rows.each { |row| self << row }
  697. #
  698. # This method returns the table for chaining.
  699. #
  700. def push(*rows)
  701. rows.each { |row| self << row }
  702. self # for chaining
  703. end
  704. #
  705. # Removes and returns the indicated column or row. In the default mixed
  706. # mode indices refer to rows and everything else is assumed to be a column
  707. # header. Use by_col!() or by_row!() to force the lookup.
  708. #
  709. def delete(index_or_header)
  710. if @mode == :row or # by index
  711. (@mode == :col_or_row and index_or_header.is_a? Integer)
  712. @table.delete_at(index_or_header)
  713. else # by header
  714. @table.map { |row| row.delete(index_or_header).last }
  715. end
  716. end
  717. #
  718. # Removes any column or row for which the block returns +true+. In the
  719. # default mixed mode or row mode, iteration is the standard row major
  720. # walking of rows. In column mode, interation will +yield+ two element
  721. # tuples containing the column name and an Array of values for that column.
  722. #
  723. # This method returns the table for chaining.
  724. #
  725. def delete_if(&block)
  726. if @mode == :row or @mode == :col_or_row # by index
  727. @table.delete_if(&block)
  728. else # by header
  729. to_delete = Array.new
  730. headers.each_with_index do |header, i|
  731. to_delete << header if block[[header, self[header]]]
  732. end
  733. to_delete.map { |header| delete(header) }
  734. end
  735. self # for chaining
  736. end
  737. include Enumerable
  738. #
  739. # In the default mixed mode or row mode, iteration is the standard row major
  740. # walking of rows. In column mode, interation will +yield+ two element
  741. # tuples containing the column name and an Array of values for that column.
  742. #
  743. # This method returns the table for chaining.
  744. #
  745. def each(&block)
  746. if @mode == :col
  747. headers.each { |header| block[[header, self[header]]] }
  748. else
  749. @table.each(&block)
  750. end
  751. self # for chaining
  752. end
  753. # Returns +true+ if all rows of this table ==() +other+'s rows.
  754. def ==(other)
  755. @table == other.table
  756. end
  757. #
  758. # Returns the table as an Array of Arrays. Headers will be the first row,
  759. # then all of the field rows will follow.
  760. #
  761. def to_a
  762. @table.inject([headers]) do |array, row|
  763. if row.header_row?
  764. array
  765. else
  766. array + [row.fields]
  767. end
  768. end
  769. end
  770. #
  771. # Returns the table as a complete CSV String. Headers will be listed first,
  772. # then all of the field rows.
  773. #
  774. # This method assumes you want the Table.headers(), unless you explicitly
  775. # pass <tt>:write_headers => false</tt>.
  776. #
  777. def to_csv(options = Hash.new)
  778. wh = options.fetch(:write_headers, true)
  779. @table.inject(wh ? [headers.to_csv(options)] : [ ]) do |rows, row|
  780. if row.header_row?
  781. rows
  782. else
  783. rows + [row.fields.to_csv(options)]
  784. end
  785. end.join
  786. end
  787. alias_method :to_s, :to_csv
  788. # Shows the mode and size of this table in a US-ASCII String.
  789. def inspect
  790. "#<#{self.class} mode:#{@mode} row_count:#{to_a.size}>".encode("US-ASCII")
  791. end
  792. end
  793. # The error thrown when the parser encounters illegal CSV formatting.
  794. class MalformedCSVError < RuntimeError; end
  795. #
  796. # A FieldInfo Struct contains details about a field's position in the data
  797. # source it was read from. CSV will pass this Struct to some blocks that make
  798. # decisions based on field structure. See CSV.convert_fields() for an
  799. # example.
  800. #
  801. # <b><tt>index</tt></b>:: The zero-based index of the field in its row.
  802. # <b><tt>line</tt></b>:: The line of the data source this row is from.
  803. # <b><tt>header</tt></b>:: The header for the column, when available.
  804. #
  805. FieldInfo = Struct.new(:index, :line, :header)
  806. # A Regexp used to find and convert some common Date formats.
  807. DateMatcher = / \A(?: (\w+,?\s+)?\w+\s+\d{1,2},?\s+\d{2,4} |
  808. \d{4}-\d{2}-\d{2} )\z /x
  809. # A Regexp used to find and convert some common DateTime formats.
  810. DateTimeMatcher =
  811. / \A(?: (\w+,?\s+)?\w+\s+\d{1,2}\s+\d{1,2}:\d{1,2}:\d{1,2},?\s+\d{2,4} |
  812. \d{4}-\d{2}-\d{2}\s\d{2}:\d{2}:\d{2} )\z /x
  813. # The encoding used by all converters.
  814. ConverterEncoding = Encoding.find("UTF-8")
  815. #
  816. # This Hash holds the built-in converters of CSV that can be accessed by name.
  817. # You can select Converters with CSV.convert() or through the +options+ Hash
  818. # passed to CSV::new().
  819. #
  820. # <b><tt>:integer</tt></b>:: Converts any field Integer() accepts.
  821. # <b><tt>:float</tt></b>:: Converts any field Float() accepts.
  822. # <b><tt>:numeric</tt></b>:: A combination of <tt>:integer</tt>
  823. # and <tt>:float</tt>.
  824. # <b><tt>:date</tt></b>:: Converts any field Date::parse() accepts.
  825. # <b><tt>:date_time</tt></b>:: Converts any field DateTime::parse() accepts.
  826. # <b><tt>:all</tt></b>:: All built-in converters. A combination of
  827. # <tt>:date_time</tt> and <tt>:numeric</tt>.
  828. #
  829. # All built-in converters transcode field data to UTF-8 before attempting a
  830. # conversion. If your data cannot be transcoded to UTF-8 the conversion will
  831. # fail and the field will remain unchanged.
  832. #
  833. # This Hash is intentionally left unfrozen and users should feel free to add
  834. # values to it that can be accessed by all CSV objects.
  835. #
  836. # To add a combo field, the value should be an Array of names. Combo fields
  837. # can be nested with other combo fields.
  838. #
  839. Converters = { integer: lambda { |f|
  840. Integer(f.encode(ConverterEncoding)) rescue f
  841. },
  842. float: lambda { |f|
  843. Float(f.encode(ConverterEncoding)) rescue f
  844. },
  845. numeric: [:integer, :float],
  846. date: lambda { |f|
  847. begin
  848. e = f.encode(ConverterEncoding)
  849. e =~ DateMatcher ? Date.parse(e) : f
  850. rescue # encoding conversion or date parse errors
  851. f
  852. end
  853. },
  854. date_time: lambda { |f|
  855. begin
  856. e = f.encode(ConverterEncoding)
  857. e =~ DateTimeMatcher ? DateTime.parse(e) : f
  858. rescue # encoding conversion or date parse errors
  859. f
  860. end
  861. },
  862. all: [:date_time, :numeric] }
  863. #
  864. # This Hash holds the built-in header converters of CSV that can be accessed
  865. # by name. You can select HeaderConverters with CSV.header_convert() or
  866. # through the +options+ Hash passed to CSV::new().
  867. #
  868. # <b><tt>:downcase</tt></b>:: Calls downcase() on the header String.
  869. # <b><tt>:symbol</tt></b>:: The header String is downcased, spaces are
  870. # replaced with underscores, non-word characters
  871. # are dropped, and finally to_sym() is called.
  872. #
  873. # All built-in header converters transcode header data to UTF-8 before
  874. # attempting a conversion. If your data cannot be transcoded to UTF-8 the
  875. # conversion will fail and the header will remain unchanged.
  876. #
  877. # This Hash is intetionally left unfrozen and users should feel free to add
  878. # values to it that can be accessed by all CSV objects.
  879. #
  880. # To add a combo field, the value should be an Array of names. Combo fields
  881. # can be nested with other combo fields.
  882. #
  883. HeaderConverters = {
  884. downcase: lambda { |h| h.encode(ConverterEncoding).downcase },
  885. symbol: lambda { |h|
  886. h.encode(ConverterEncoding).downcase.gsub(/\s+/, "_").
  887. gsub(/\W+/, "").to_sym
  888. }
  889. }
  890. #
  891. # The options used when no overrides are given by calling code. They are:
  892. #
  893. # <b><tt>:col_sep</tt></b>:: <tt>","</tt>
  894. # <b><tt>:row_sep</tt></b>:: <tt>:auto</tt>
  895. # <b><tt>:quote_char</tt></b>:: <tt>'"'</tt>
  896. # <b><tt>:field_size_limit</tt></b>:: +nil+
  897. # <b><tt>:converters</tt></b>:: +nil+
  898. # <b><tt>:unconverted_fields</tt></b>:: +nil+
  899. # <b><tt>:headers</tt></b>:: +false+
  900. # <b><tt>:return_headers</tt></b>:: +false+
  901. # <b><tt>:header_converters</tt></b>:: +nil+
  902. # <b><tt>:skip_blanks</tt></b>:: +false+
  903. # <b><tt>:force_quotes</tt></b>:: +false+
  904. #
  905. DEFAULT_OPTIONS = { col_sep: ",",
  906. row_sep: :auto,
  907. quote_char: '"',
  908. field_size_limit: nil,
  909. converters: nil,
  910. unconverted_fields: nil,
  911. headers: false,
  912. return_headers: false,
  913. header_converters: nil,
  914. skip_blanks: false,
  915. force_quotes: false }.freeze
  916. #
  917. # This method will return a CSV instance, just like CSV::new(), but the
  918. # instance will be cached and returned for all future calls to this method for
  919. # the same +data+ object (tested by Object#object_id()) with the same
  920. # +options+.
  921. #
  922. # If a block is given, the instance is passed to the block and the return
  923. # value becomes the return value of the block.
  924. #
  925. def self.instance(data = $stdout, options = Hash.new)
  926. # create a _signature_ for this method call, data object and options
  927. sig = [data.object_id] +
  928. options.values_at(*DEFAULT_OPTIONS.keys.sort_by { |sym| sym.to_s })
  929. # fetch or create the instance for this signature
  930. @@instances ||= Hash.new
  931. instance = (@@instances[sig] ||= new(data, options))
  932. if block_given?
  933. yield instance # run block, if given, returning result
  934. else
  935. instance # or return the instance
  936. end
  937. end
  938. #
  939. # This method allows you to serialize an Array of Ruby objects to a String or
  940. # File of CSV data. This is not as powerful as Marshal or YAML, but perhaps
  941. # useful for spreadsheet and database interaction.
  942. #
  943. # Out of the box, this method is intended to work with simple data objects or
  944. # Structs. It will serialize a list of instance variables and/or
  945. # Struct.members().
  946. #
  947. # If you need need more complicated serialization, you can control the process
  948. # by adding methods to the class to be serialized.
  949. #
  950. # A class method csv_meta() is responsible for returning the first row of the
  951. # document (as an Array). This row is considered to be a Hash of the form
  952. # key_1,value_1,key_2,value_2,... CSV::load() expects to find a class key
  953. # with a value of the stringified class name and CSV::dump() will create this,
  954. # if you do not define this method. This method is only called on the first
  955. # object of the Array.
  956. #
  957. # The next method you can provide is an instance method called csv_headers().
  958. # This method is expected to return the second line of the document (again as
  959. # an Array), which is to be used to give each column a header. By default,
  960. # CSV::load() will set an instance variable if the field header starts with an
  961. # @ character or call send() passing the header as the method name and
  962. # the field value as an argument. This method is only called on the first
  963. # object of the Array.
  964. #
  965. # Finally, you can provide an instance method called csv_dump(), which will
  966. # be passed the headers. This should return an Array of fields that can be
  967. # serialized for this object. This method is called once for every object in
  968. # the Array.
  969. #
  970. # The +io+ parameter can be used to serialize to a File, and +options+ can be
  971. # anything CSV::new() accepts.
  972. #
  973. def self.dump(ary_of_objs, io = "", options = Hash.new)
  974. obj_template = ary_of_objs.first
  975. csv = new(io, options)
  976. # write meta information
  977. begin
  978. csv << obj_template.class.csv_meta
  979. rescue NoMethodError
  980. csv << [:class, obj_template.class]
  981. end
  982. # write headers
  983. begin
  984. headers = obj_template.csv_headers
  985. rescue NoMethodError
  986. headers = obj_template.instance_variables.sort
  987. if obj_template.class.ancestors.find { |cls| cls.to_s =~ /\AStruct\b/ }
  988. headers += obj_template.members.map { |mem| "#{mem}=" }.sort
  989. end
  990. end
  991. csv << headers
  992. # serialize each object
  993. ary_of_objs.each do |obj|
  994. begin
  995. csv << obj.csv_dump(headers)
  996. rescue NoMethodError
  997. csv << headers.map do |var|
  998. if var[0] == ?@
  999. obj.instance_variable_get(var)
  1000. else
  1001. obj[var[0..-2]]
  1002. end
  1003. end
  1004. end
  1005. end
  1006. if io.is_a? String
  1007. csv.string
  1008. else
  1009. csv.close
  1010. end
  1011. end
  1012. #
  1013. # This method is the reading counterpart to CSV::dump(). See that method for
  1014. # a detailed description of the process.
  1015. #
  1016. # You can customize loading by adding a class method called csv_load() which
  1017. # will be passed a Hash of meta information, an Array of headers, and an Array
  1018. # of fields for the object the method is expected to return.
  1019. #
  1020. # Remember that all fields will be Strings after this load. If you need
  1021. # something else, use +options+ to setup converters or provide a custom
  1022. # csv_load() implementation.
  1023. #
  1024. def self.load(io_or_str, options = Hash.new)
  1025. csv = new(io_or_str, options)
  1026. # load meta information
  1027. meta = Hash[*csv.shift]
  1028. cls = meta["class".encode(csv.encoding)].split("::".encode(csv.encoding)).
  1029. inject(Object) do |c, const|
  1030. c.const_get(const)
  1031. end
  1032. # load headers
  1033. headers = csv.shift
  1034. # unserialize each object stored in the file
  1035. results = csv.inject(Array.new) do |all, row|
  1036. begin
  1037. obj = cls.csv_load(meta, headers, row)
  1038. rescue NoMethodError
  1039. obj = cls.allocate
  1040. headers.zip(row) do |name, value|
  1041. if name[0] == ?@
  1042. obj.instance_variable_set(name, value)
  1043. else
  1044. obj.send(name, value)
  1045. end
  1046. end
  1047. end
  1048. all << obj
  1049. end
  1050. csv.close unless io_or_str.is_a? String
  1051. results
  1052. end
  1053. #
  1054. # :call-seq:
  1055. # filter( options = Hash.new ) { |row| ... }
  1056. # filter( input, options = Hash.new ) { |row| ... }
  1057. # filter( input, output, options = Hash.new ) { |row| ... }
  1058. #
  1059. # This method is a convenience for building Unix-like filters for CSV data.
  1060. # Each row is yielded to the provided block which can alter it as needed.
  1061. # After the block returns, the row is appended to +output+ altered or not.
  1062. #
  1063. # The +input+ and +output+ arguments can be anything CSV::new() accepts
  1064. # (generally String or IO objects). If not given, they default to
  1065. # <tt>ARGF</tt> and <tt>$stdout</tt>.
  1066. #
  1067. # The +options+ parameter is also filtered down to CSV::new() after some
  1068. # clever key parsing. Any key beginning with <tt>:in_</tt> or
  1069. # <tt>:input_</tt> will have that leading identifier stripped and will only
  1070. # be used in the +options+ Hash for the +input+ object. Keys starting with
  1071. # <tt>:out_</tt> or <tt>:output_</tt> affect only +output+. All other keys
  1072. # are assigned to both objects.
  1073. #
  1074. # The <tt>:output_row_sep</tt> +option+ defaults to
  1075. # <tt>$INPUT_RECORD_SEPARATOR</tt> (<tt>$/</tt>).
  1076. #
  1077. def self.filter(*args)
  1078. # parse options for input, output, or both
  1079. in_options, out_options = Hash.new, {row_sep: $INPUT_RECORD_SEPARATOR}
  1080. if args.last.is_a? Hash
  1081. args.pop.each do |key, value|
  1082. case key.to_s
  1083. when /\Ain(?:put)?_(.+)\Z/
  1084. in_options[$1.to_sym] = value
  1085. when /\Aout(?:put)?_(.+)\Z/
  1086. out_options[$1.to_sym] = value
  1087. else
  1088. in_options[key] = value
  1089. out_options[key] = value
  1090. end
  1091. end
  1092. end
  1093. # build input and output wrappers
  1094. input = new(args.shift || ARGF, in_options)
  1095. output = new(args.shift || $stdout, out_options)
  1096. # read, yield, write
  1097. input.each do |row|
  1098. yield row
  1099. output << row
  1100. end
  1101. end
  1102. #
  1103. # This method is intended as the primary interface for reading CSV files. You
  1104. # pass a +path+ and any +options+ you wish to set for the read. Each row of
  1105. # file will be passed to the provided +block+ in turn.
  1106. #
  1107. # The +options+ parameter can be anything CSV::new() understands. This method
  1108. # also understands an additional <tt>:encoding</tt> parameter that you can use
  1109. # to specify the Encoding of the data in the file to be read. You must provide
  1110. # this unless your data is in Encoding::default_external(). CSV will use this
  1111. # to deterime how to parse the data. You may provide a second Encoding to
  1112. # have the data transcoded as it is read. For example,
  1113. # <tt>encoding: "UTF-32BE:UTF-8"</tt> would read UTF-32BE data from the file
  1114. # but transcode it to UTF-8 before CSV parses it.
  1115. #
  1116. def self.foreach(path, options = Hash.new, &block)
  1117. encoding = options.delete(:encoding)
  1118. mode = "rb"
  1119. mode << ":#{encoding}" if encoding
  1120. open(path, mode, options) do |csv|
  1121. csv.each(&block)
  1122. end
  1123. end
  1124. #
  1125. # :call-seq:
  1126. # generate( str, options = Hash.new ) { |csv| ... }
  1127. # generate( options = Hash.new ) { |csv| ... }
  1128. #
  1129. # This method wraps a String you provide, or an empty default String, in a
  1130. # CSV object which is passed to the provided block. You can use the block to
  1131. # append CSV rows to the String and when the block exits, the final String
  1132. # will be returned.
  1133. #
  1134. # Note that a passed String *is* modfied by this method. Call dup() before
  1135. # passing if you need a new String.
  1136. #
  1137. # The +options+ parameter can be anything CSV::new() understands. This method
  1138. # understands an additional <tt>:encoding</tt> parameter when not passed a
  1139. # String to set the base Encoding for the output. CSV needs this hint if you
  1140. # plan to output non-ASCII compatible data.
  1141. #
  1142. def self.generate(*args)
  1143. # add a default empty String, if none was given
  1144. if args.first.is_a? String
  1145. io = StringIO.new(args.shift)
  1146. io.seek(0, IO::SEEK_END)
  1147. args.unshift(io)
  1148. else
  1149. encoding = args.last.is_a?(Hash) ? args.last.delete(:encoding) : nil
  1150. str = ""
  1151. str.encode!(encoding) if encoding
  1152. args.unshift(str)
  1153. end
  1154. csv = new(*args) # wrap
  1155. yield csv # yield for appending
  1156. csv.string # return final String
  1157. end
  1158. #
  1159. # This method is a shortcut for converting a single row (Array) into a CSV
  1160. # String.
  1161. #
  1162. # The +options+ parameter can be anything CSV::new() understands. This method
  1163. # understands an additional <tt>:encoding</tt> parameter to set the base
  1164. # Encoding for the output. This method will try to guess your Encoding from
  1165. # the first non-+nil+ field in +row+, if possible, but you may need to use
  1166. # this parameter as a backup plan.
  1167. #
  1168. # The <tt>:row_sep</tt> +option+ defaults to <tt>$INPUT_RECORD_SEPARATOR</tt>
  1169. # (<tt>$/</tt>) when calling this method.
  1170. #
  1171. def self.generate_line(row, options = Hash.new)
  1172. options = {row_sep: $INPUT_RECORD_SEPARATOR}.merge(options)
  1173. encoding = options.delete(:encoding)
  1174. str = ""
  1175. if encoding
  1176. str.force_encoding(encoding)
  1177. elsif field = row.find { |f| not f.nil? }
  1178. str.force_encoding(String(field).encoding)
  1179. end
  1180. (new(str, options) << row).string
  1181. end
  1182. #
  1183. # :call-seq:
  1184. # open( filename, mode = "rb", options = Hash.new ) { |faster_csv| ... }
  1185. # open( filename, options = Hash.new ) { |faster_csv| ... }
  1186. # open( filename, mode = "rb", options = Hash.new )
  1187. # open( filename, options = Hash.new )
  1188. #
  1189. # This method opens an IO object, and wraps that with CSV. This is intended
  1190. # as the primary interface for writing a CSV file.
  1191. #
  1192. # You must pass a +filename+ and may optionally add a +mode+ for Ruby's
  1193. # open(). You may also pass an optional Hash containing any +options+
  1194. # CSV::new() understands as the final argument.
  1195. #
  1196. # This method works like Ruby's open() call, in that it will pass a CSV object
  1197. # to a provided block and close it when the block terminates, or it will
  1198. # return the CSV object when no block is provided. (*Note*: This is different
  1199. # from the Ruby 1.8 CSV library which passed rows to the block. Use
  1200. # CSV::foreach() for that behavior.)
  1201. #
  1202. # You must provide a +mode+ with an embedded Encoding designator unless your
  1203. # data is in Encoding::default_external(). CSV will check the Encoding of the
  1204. # underlying IO object (set by the +mode+ you pass) to deterime how to parse
  1205. # the data. You may provide a second Encoding to have the data transcoded as
  1206. # it is read just as you can with a normal call to IO::open(). For example,
  1207. # <tt>"rb:UTF-32BE:UTF-8"</tt> would read UTF-32BE data from the file but
  1208. # transcode it to UTF-8 before CSV parses it.
  1209. #
  1210. # An opened CSV object will delegate to many IO methods for convenience. You
  1211. # may call:
  1212. #
  1213. # * binmode()
  1214. # * binmode?()
  1215. # * close()
  1216. # * close_read()
  1217. # * close_write()
  1218. # * closed?()
  1219. # * eof()
  1220. # * eof?()
  1221. # * external_encoding()
  1222. # * fcntl()
  1223. # * fileno()
  1224. # * flock()
  1225. # * flush()
  1226. # * fsync()
  1227. # * internal_encoding()
  1228. # * ioctl()
  1229. # * isatty()
  1230. # * path()
  1231. # * pid()
  1232. # * pos()
  1233. # * pos=()
  1234. # * reopen()
  1235. # * seek()
  1236. # * stat()
  1237. # * sync()
  1238. # * sync=()
  1239. # * tell()
  1240. # * to_i()
  1241. # * to_io()
  1242. # * truncate()
  1243. # * tty?()
  1244. #
  1245. def self.open(*args)
  1246. # find the +options+ Hash
  1247. options = if args.last.is_a? Hash then args.pop else Hash.new end
  1248. # default to a binary open mode
  1249. args << "rb" if args.size == 1
  1250. # wrap a File opened with the remaining +args+
  1251. csv = new(File.open(*args), options)
  1252. # handle blocks like Ruby's open(), not like the CSV library
  1253. if block_given?
  1254. begin
  1255. yield csv
  1256. ensure
  1257. csv.close
  1258. end
  1259. else
  1260. csv
  1261. end
  1262. end
  1263. #
  1264. # :call-seq:
  1265. # parse( str, options = Hash.new ) { |row| ... }
  1266. # parse( str, options = Hash.new )
  1267. #
  1268. # This method can be used to easily parse CSV out of a String. You may either
  1269. # provide a +block+ which will be called with each row of the String in turn,
  1270. # or just use the returned Array of Arrays (when no +block+ is given).
  1271. #
  1272. # You pass your +str+ to read from, and an optional +options+ Hash containing
  1273. # anything CSV::new() understands.
  1274. #
  1275. def self.parse(*args, &block)
  1276. csv = new(*args)
  1277. if block.nil? # slurp contents, if no block is given
  1278. begin
  1279. csv.read
  1280. ensure
  1281. csv.close
  1282. end
  1283. else # or pass each row to a provided block
  1284. csv.each(&block)
  1285. end
  1286. end
  1287. #
  1288. # This method is a shortcut for converting a single line of a CSV String into
  1289. # a into an Array. Note that if +line+ contains multiple rows, anything
  1290. # beyond the first row is ignored.
  1291. #
  1292. # The +options+ parameter can be anything CSV::new() understands.
  1293. #
  1294. def self.parse_line(line, options = Hash.new)
  1295. new(line, options).shift
  1296. end
  1297. #
  1298. # Use to slurp a CSV file into an Array of Arrays. Pass the +path+ to the
  1299. # file and any +options+ CSV::new() understands. This method also understands
  1300. # an additional <tt>:encoding</tt> parameter that you can use to specify the
  1301. # Encoding of the data in the file to be read. You must provide this unless
  1302. # your data is in Encoding::default_external(). CSV will use this to deterime
  1303. # how to parse the data. You may provide a second Encoding to have the data
  1304. # transcoded as it is read. For example,
  1305. # <tt>encoding: "UTF-32BE:UTF-8"</tt> would read UTF-32BE data from the file
  1306. # but transcode it to UTF-8 before CSV parses it.
  1307. #
  1308. def self.read(path, options = Hash.new)
  1309. encoding = options.delete(:encoding)
  1310. mode = "rb"
  1311. mode << ":#{encoding}" if encoding
  1312. open(path, mode, options) { |csv| csv.read }
  1313. end
  1314. # Alias for CSV::read().
  1315. def self.readlines(*args)
  1316. read(*args)
  1317. end
  1318. #
  1319. # A shortcut for:
  1320. #
  1321. # CSV.read( path, { headers: true,
  1322. # converters: :numeric,
  1323. # header_converters: :symbol }.merge(options) )
  1324. #
  1325. def self.table(path, options = Hash.new)
  1326. read( path, { headers: true,
  1327. converters: :numeric,
  1328. header_converters: :symbol }.merge(options) )
  1329. end
  1330. #
  1331. # This constructor will wrap either a String or IO object passed in +data+ for
  1332. # reading and/or writing. In addition to the CSV instance methods, several IO
  1333. # methods are delegated. (See CSV::open() for a complete list.) If you pass
  1334. # a String for +data+, you can later retrieve it (after writing to it, for
  1335. # example) with CSV.string().
  1336. #
  1337. # Note that a wrapped String will be positioned at at the beginning (for
  1338. # reading). If you want it at the end (for writing), use CSV::generate().
  1339. # If you want any other positioning, pass a preset StringIO object instead.
  1340. #
  1341. # You may set any reading and/or writing preferences in the +options+ Hash.
  1342. # Available options are:
  1343. #
  1344. # <b><tt>:col_sep</tt></b>:: The String placed between each field.
  1345. # This String will be transcoded into
  1346. # the data's Encoding before par…

Large files files are truncated, but you can click here to view the full file