PageRenderTime 85ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 1ms

/Languages/Ruby/StdLib/ruby/1.9.1/csv.rb

http://github.com/IronLanguages/main
Ruby | 2330 lines | 962 code | 171 blank | 1197 comment | 150 complexity | 19d328e15d555b5dfdac1e47bf2c4a02 MD5 | raw file
Possible License(s): CPL-1.0, BSD-3-Clause, ISC, GPL-2.0, MPL-2.0-no-copyleft-exception

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

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