CSV with Ruby Newbie

P

pete.roome

Hey guys.

I am currently following an example in: "Programming Ruby: The Pragmatic
Programmers Guide" (pg. 663) on reading CSV files with Ruby. I am
struggling though to get the code to read a CSV file that has a header
in it. I have copied the example exactly but get the following error:

undefined method `process' for main:Object (NoMethodError)
from /usr/local/lib/ruby/1.8/csv.rb:560:in `each'
from solution.rb:4

My Code:

require 'csv'
reader = CSV.open("csvfile", "r")
header = reader.shift
reader.each{|row| process(header, row)}
CSV.open("csvfile", "r") do |row|
qty = row[0].to_i
price = row[2].to_f
printf "%20s: $%5.2f %s\n", row[1], qty*price, row[3] || " ---"
end

(If your looking in the book then i have just adapted the csvfile to be
the same as csvfile_hdr)


Would really appreciate it if someone could perhaps point out what i am
doing wrong please. Thanks
 
B

briefcase.speakers

Zoltar said:
undefined method `process' for main:Object (NoMethodError)
from /usr/local/lib/ruby/1.8/csv.rb:560:in `each'
from solution.rb:4

Does the book define a "process" function? The code below would require
you to define a function process that does whatever it is you need to do
with the header.
reader.each{|row| process(header, row)}

ex-
def process( header, row )
# do something with header
# do something with row
end

If process is a method of the CSV module, you'd need to prefix it with
CSV:: to get it to work.
 
P

pete.roome

Adam said:
Does the book define a "process" function? The code below would require
you to define a function process that does whatever it is you need to do
with the header.


ex-
def process( header, row )
# do something with header
# do something with row
end

If process is a method of the CSV module, you'd need to prefix it with
CSV:: to get it to work.


Hmmmm no there is no definition of the function 'process' in the book, i
can't see header as being a CSV module either.

The book starts simply with:

CSV...
Count, Description, Price
12,eggs,2.89,
2,"shirt, blue",21.45,special
1,"""Hello Kitty"" bag",13.99

Ruby...

require 'csv'

CSV.open("csvfile", "r") do |row|
qty = row[0].to_i
price = row[2].to_f
printf "%20s: $%5.2f %s\n", row[1], qty*price, row[3] || " ---"
end

Output...

Description: $ 0.00 ---
eggs: $34.68 ---
shirt, blue: $42.90 special
"Hello Kitty" bag: $13.99 ---

It then says:
"Some CSV files have a header line. Read it, and then process the rest
of the file."

and the Ruby provided is:

require 'csv'
reader = CSV.open("csvfile", "r")
header = reader.shift
reader.each {|row| process(header, row)}
 
W

wemagor2

That example is making an assumption that you will write the 'process'
method.

Change the 2nd CSV.open line to:
def process(header,row)

Then move the 'process' method to just after the 'require' line. That
should do it for you.
 
R

rhkramer

undefined method `process' for main:Object (NoMethodError)
from /usr/local/lib/ruby/1.8/csv.rb:560:in `each'
from solution.rb:4

Have you written/defined a method named "process"--it looks to me like they
(in the book) have used "process" as sort of a generic method--something that
doesn't exist (and isn't defined on that page) that you will have to write
for yourself.

Randy Kramer
require 'csv'
reader = CSV.open("csvfile", "r")
header = reader.shift
reader.each{|row| process(header, row)}
CSV.open("csvfile", "r") do |row|
qty = row[0].to_i
price = row[2].to_f
printf "%20s: $%5.2f %s\n", row[1], qty*price, row[3] || " ---"
end
 
P

pete.roome

Wayne said:
That example is making an assumption that you will write the 'process'
method.

Change the 2nd CSV.open line to:
def process(header,row)

Then move the 'process' method to just after the 'require' line. That
should do it for you.

Wayne,

Thanks alot that works.

So how would i go about displaying the headers above each row then?
 
W

wemagor2

So how would i go about displaying the headers above each row then?

The header variable is just an array of strings, so you can just print
header[0],header[1] and so on, but they won't line up with the data
you're printing from the rows. You should be able to figure out the
width of each data item.

The way it's being printed doesn't correspond to the headers any longer,
so you would have to make up your own headers. Something like this:

printf "%20s %7s %s\n\n", header[1], header[2], "Is it a special"
 
P

pete.roome

Wayne said:
So how would i go about displaying the headers above each row then?

The header variable is just an array of strings, so you can just print
header[0],header[1] and so on, but they won't line up with the data
you're printing from the rows. You should be able to figure out the
width of each data item.

The way it's being printed doesn't correspond to the headers any longer,
so you would have to make up your own headers. Something like this:

printf "%20s %7s %s\n\n", header[1], header[2], "Is it a special"

Ok brilliant that makes sense. Thanks alot for your help!

Pete
 
B

bbxx789_05ss

Zoltar said:
Hey guys.

I am currently following an example in: "Programming Ruby: The Pragmatic
Programmers Guide" (pg. 663) on reading CSV files with Ruby. I am
struggling though to get the code to read a CSV file that has a header
in it. I have copied the example exactly but get the following error:

undefined method `process' for main:Object (NoMethodError)
from /usr/local/lib/ruby/1.8/csv.rb:560:in `each'
from solution.rb:4

My Code:

require 'csv'
reader = CSV.open("csvfile", "r")
header = reader.shift
reader.each{|row| process(header, row)}

The book has a bad habit of calling non-existent functions in the
examples, so you have to be on the lookout for them. As a consequence,
a number of examples won't run as presented. However the introduction
(in pickaxe2, p.5) says that you can download source code for the book
that will run, i.e. presumably the method process() will be defined in
the downloaded source.

I think the book should say something like this instead:

read.each do |row|
#process row however you see fit
end

so that beginners won't get errors when they copy the examples verbatim.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,009
Latest member
GidgetGamb

Latest Threads

Top