Я бы предложил использовать функцию CSV::header_row для выполнения проверки и поднять ошибку, если это не то, что вы ожидаете. Что-то вроде:
def ReadLongFile(longFile)
CSV.foreach(longFile, :headers => true, :return_headers => true, :col_sep => '|') do |row|
if row.header_row? then
raise ArgumentError, "Bad headers" unless header_sane?(row)
end
# Otherwise do the processing
end
end
Ваш header_sane?
реализации внешних выполнит проверку, что вам нужно, чтобы убедиться, что файл, что вы ожидаете, что это будет. Ваш код вызова может спасти ArgumentError, если он может восстановиться из него, или просто дать ему сбой :-)
Примечание: Обновлено, чтобы отразить ошибку, указанную в комментариях ниже. Обязательно установите опцию: return_headers при вызове CSV::foreach.
Если вы беспокоитесь о минимальных издержках вызова header_row? для каждой записи строки вы можете создать экземпляр CSV и использовать shift для ручной проверки первой строки перед продолжением. Например:
def ReadLongFile(longFile)
File.open(longFile) do |file|
reader = CSV.new(file, {:col_sep => '|', :headers => true, :return_headers => true})
header_row = reader.shift
raise ArgumentError, "Bad file headers" unless header_sane?(header_row)
reader.each do |row|
p row
end
end
end
Реализовано, как указано выше, следующее поведение справедливо:
[4] pry(main)> def header_sane? row
[4] pry(main)* true
[4] pry(main)* end
=> nil
[5] pry(main)> ReadLongFile("file.csv")
#<CSV::Row "date":"2010-01-01" "time":"07:00:00" "account":"A1">
#<CSV::Row "date":"2010-01-01" "time":"07:00:01" "account":"A2">
=> nil
[6] pry(main)> def header_sane? row
[6] pry(main)* false
[6] pry(main)* end
=> nil
[7] pry(main)> ReadLongFile("file.csv")
ArgumentError: Bad file headers
from (pry):7:in `block in ReadLongFile'
Это неправильно. Первый 'is_header?' В вашей функции должен быть 'header_row?'. Кроме того, необходимо установить ': return_headers' значение true. – idealistikz
@idealistikz соответственно обновлено - спасибо! –