Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Create a new Ruby CSV object with headers in a single csv.new() line

Tags:

ruby

csv

I'm trying to create a new CSV object with only the header row in it, but the headers are not set until I call read():

[32] pry(main)> c = CSV.new("Keyword,Index,Page,Index in Page,Type,Title,URL", :headers => :first_row, :write_headers => true, :return_headers => true)
=> <#CSV io_type:StringIO encoding:UTF-8 lineno:0 col_sep:"," row_sep:"\n" quote_char:"\"" headers:true>
[33] pry(main)> c.headers
=> true
[34] pry(main)> c.read
=> #<CSV::Table mode:col_or_row row_count:1>
[35] pry(main)> c.headers
=> ["Keyword", "Index", "Page", "Index in Page", "Type", "Title", "URL"]

Why is that? Why can't I get a properly working CSV object with my single CSV.new line?

like image 745
Yaya Avatar asked Nov 29 '12 17:11

Yaya


People also ask

Can't process the CSV illegal quoting in line?

Illegal quoting on lineThis error is caused when there is an illegal character in the CSV file that you are trying to import. To fix this, remember that your CSV file must be UTF-8 encoded. Sometimes, this error is caused by a missing or stray quote.

What does CSV parse Do Ruby?

The parser works in the Encoding of the IO or String object being read from or written to. Your data is never transcoded (unless you ask Ruby to transcode it for you) and will literally be parsed in the Encoding it is in. Thus CSV will return Arrays or Rows of Strings in the Encoding of your data.


2 Answers

As the documentation will tell you it's treating the string as if it were the contents of a file (i.e. StringIO) so you still have to read the string just as you would any other IO source.

If you want to set the headers explicitly, you pass an array as the :headers parameter.

like image 94
Sean Redmond Avatar answered Oct 22 '22 05:10

Sean Redmond


There does not appear to be a way to do this in one call but you can easily remedy that with a custom method of your own:

Given:

def new_csv(headers, data)
  csv = CSV.new(data, headers: headers, write_headers: true, return_headers: true)
  csv.read
  csv
end

You can call use it as:

csv = new_csv("Header 1, Header 2", "abc,def") 
=> <#CSV io_type:StringIO encoding:UTF-8 lineno:1 col_sep:"," row_sep:"\n" quote_char:"\"" headers:["abc", "def"]>

csv.headers
=> ["Header 1", "Header 2"]

Hope that helps.

like image 2
jboursiquot Avatar answered Oct 22 '22 06:10

jboursiquot