csv.foreach stuck, not calling the block
I am trying to write a CSV "fixer". Unfortunately It seems that the csv.foreach instruction is not calling the lambda I have created. The CPU is used at 100%. Just wondering what ruby is doing in the meantime...开发者_如何转开发
Any ideas why my code is wrong?
1 require "csv"
2
3 ARGV.empty? do
4 print "usage: fixcsv.rb <filename>"
5 exit
6 end
7
8 filename_orig = Dir.pwd + "/" + ARGV[0]
9 filename_dest = filename_orig.sub(/csv$/,"tmp.csv")
10 topic = filename_orig.sub(/_entries.csv$/,"").sub(/.*\//,"")
11
12 puts "topic:" + topic
13
14 writer = CSV.open(filename_dest,"w",:col_sep=>";")
15 #i=0
16 cycler = lambda do |row|
17 #i = i + 1
18 #puts "row number:" + i.to_str
19 #row[17] = topic
20 puts "foo"
21 writer << row
22 end
23
24 begin
25 CSV.foreach(filename_orig,:col_sep=>",",&cycler)
26 rescue
27 puts "exception:" + $!.message
28 exit
29 else
30 writer.close
31 end
Here is the stack trace produced when I Ctrl-C it:
stab@ubuntu:~/wok$ ruby addtopic.rb civilpoliticalrights_entries.csv
topic:civilpoliticalrights
^C/usr/lib/ruby/1.8/csv.rb:914:in `buf_size': Interrupt
from /usr/lib/ruby/1.8/csv.rb:825:in `[]'
from /usr/lib/ruby/1.8/csv.rb:354:in `parse_body'
from /usr/lib/ruby/1.8/csv.rb:227:in `parse_row'
from /usr/lib/ruby/1.8/csv.rb:637:in `get_row'
from /usr/lib/ruby/1.8/csv.rb:556:in `each'
from /usr/lib/ruby/1.8/csv.rb:531:in `parse'
from /usr/lib/ruby/1.8/csv.rb:311:in `open_reader'
from /usr/lib/ruby/1.8/csv.rb:94:in `foreach'
from addtopic.rb:25
EDIT: Ruby version is:
$ ruby --version
ruby 1.8.7 (2010-01-10 patchlevel 249) [i486-linux]
Your program worked fine for me in Ruby 1.9.
I have a few observations:
If your input pathname does not end in
csv
, then the input and output file names will be the same. This could easily produce an infinite loop.You are definitely using the 1.9 flavor of csv. If this program needs to run on 1.8.7 it would need to have patches from the snippet below...
Mods for 1.8.7:
writer = CSV.open(filename_dest, "w", ?;)
#i=0
cycler = lambda do |row|
#i = i + 1
#puts "row number:" + i.to_str
#row[17] = topic
writer << row
end
begin
CSV.open filename_orig, 'r', ?,, &cycler
The main problem with 1.8.7 csv is that the interfaces to CSV.open
and CSV.foreach
do not take Hash options. Worse, they are expecting numeric code points, a feature of Ruby that apparently didn't work out and was withdrawn in 1.9.
精彩评论