#ruby #csv #lambda
#ruby #csv #лямбда
Вопрос:
Я пытаюсь написать «исправление» CSV. К сожалению, похоже, что инструкция csv.foreach не вызывает созданный мной лямбда-выражение. Процессор используется на 100%. Просто интересно, что ruby делает в это время…
Есть идеи, почему мой код неправильный?
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=>",",amp;cycler)
26 rescue
27 puts "exception:" $!.message
28 exit
29 else
30 writer.close
31 end
Вот трассировка стека, созданная, когда я нажимаю Ctrl-C на нее:
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
РЕДАКТИРОВАТЬ: версия Ruby является:
$ ruby --version
ruby 1.8.7 (2010-01-10 patchlevel 249) [i486-linux]
Комментарии:
1. Нам нужно будет знать, на какой версии Ruby вы используете, чтобы дать хороший ответ, поскольку вы используете элементы API, которые кардинально отличаются между csv в 1.8.7 и csv в 1.9.x. Это неудачная ситуация. (Я полагаю, 1.9 может использовать старый API, но если вы используете 1.8.7, я бы предпочел просто сосредоточиться на этом.)
Ответ №1:
Ваша программа отлично работала для меня в Ruby 1.9.
У меня есть несколько наблюдений:
-
Если ваш входной путь не заканчивается на
csv
, то имена входного и выходного файлов будут одинаковыми. Это может легко привести к бесконечному циклу. -
Вы определенно используете формат csv 1.9. Если эта программа должна запускаться на версии 1.8.7, в ней должны быть исправления из приведенного ниже фрагмента…
Моды для 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', ?,, amp;cycler
Основная проблема с 1.8.7 csv заключается в том, что интерфейсы к CSV.open
и CSV.foreach
не принимают параметры хэша. Хуже того, они ожидают числовые кодовые точки, особенность Ruby, которая, по-видимому, не сработала и была удалена в 1.9.