I have been doing some testing with CSV.table. I have two small and almost identical CSV files, however one is missing the header row.
When I run CSV.table against the CSV file with the header row, everything works as expected.
When I run it against the CSV file without the header row I get:
NoMethodError: undefined method `encode' for nil:NilClass
I tried this with different types of data, with different types of headers, and get the same results.
I am curious to the magic of CSV.table. If I use CSV.parse with headers set to true, then it always makes the first row be headers no matter what. So, I have been using CSV.table to check if a CSV file being imported has a header row but I am not too comfortable with this because I don’t understand if or when it will or will not work the way I’m using it.
begin
CSV.table(csv_file_path)
rescue
# Add error to log or something.
end
Does anyone know?
P.S. I’ve already read through this and the source code it provides on each method – http://www.ruby-doc.org/stdlib-1.9.3/libdoc/csv/rdoc/CSV.html
There isn’t any magic involved, and it won’t work for you in general.
As you can see from the source,
tableliterally just callsreadwithheaders: true. But it also converts the header to symbols (header_converters: :symbol) and this is the key to why it appears to work.You get an error without headers because you have a blank column in your first row of data (something like
a,b,,d,e). The blank gets read in asnil, and sincenilcan’t be converted to a symbol, it blows up.Try it with some data that doesn’t have a blank in the first row – you’ll see that
tablewill treat that row of data as headers just like any of the other methods.