From: "NAKAMURA, Hiroshi" Date: 2004-05-20T12:19:48+09:00 Subject: Re: CSV bug? Hi, SER wrote: > BTW, the csv.rb is really nice. I wanted to thank you for it. I'm > doing a subversive Ruby project at work, and was doing it "the hard > way" before I discovered csv.rb. Now the app is smaller and more > robust. Great to hear. Thank you and all users. I recently added a feature which allows multi-char sequence as a record separator and field separator. And some incompatible changes such as CSV::Row -> Array and CSV::Cell -> String. It passes all tests as before so I believe the newer version will work for my "the hard way" thing, but API incompatibility will cause problems for many users. Sorry for users in advance. With the new version, you can do; 0% ruby -rcsv -e ' CSV::Reader.parse("a||b==c||d", "||", "==") { |r| p r } ' ["a", "b"] ["c", "d"] 0% cat matrix.csv; echo | |o -+-+- x|x|o -+-+- o| | 0% ruby -rcsv -e ' CSV.parse("matrix.csv", "|", "\n-+-+-\n") { |r| p r } ' [" ", " ", "o"] ["x", "x", "o"] ["o", " ", nil] And say your boss doesn't like open source because of security; 0% cat src.rb require 'openssl' text = ARGV.shift key = 'it is my secret key!' des = OpenSSL::Cipher::DES.new( 'EDE3', 'CBC' ) des.decrypt( key ) result = des.update( text.unpack( 'm' )[0] ) result += des.final p result 0% ruby src.rb DMZZ+eRpyQbv+nRlr6Y5BQ== "hello world" 0% ruby -rcsv -e ' CSV.generate("dest.csv", "ae", "oe") { |w| CSV.parse("src.rb", " ") { |r| w << r } } ' 0% cat dest.csv; echo requireae'openssl'oetextae=aeARGV.shiftoekeyae=ae'itaeisaemyaesecretaekey!'oedesae=aeOpenSSL::Cipher::DES.new(ae'EDE3',ae'CBC'ae)oedes.decrypt(aekeyae)oeresultae=aedes.update(aetext.unpack(ae'm'ae)[0]ae)oeresultae+=aedes.finaloepaeresultoe 0% ruby -rcsv -e ' CSV.generate("dest.rb", " ") { |w| CSV.parse("dest.csv", "ae", "oe") { |r| w << r } } ' 0% diff src.rb dest.rb 0% :-) The current version is in csv's repository located at http://www.ruby-lang.org/cgi-bin/cvsweb.cgi/lib/csv/ and I'll merge it to ruby's repository tonight. Of course at HEAD(1.9). What do you think about the branch for 1.8? I'm afraid that 1.8 users don't want incompatibilities... Here's the summary of API change (excerpted from README.txt); [CAUTION] API change: CSV::Row removed. A row is represented as just an Array. Since CSV::Row was a subclass of Array, it won't hurt almost all programs except one which depended CSV::Row#match. [CAUTION] API change: CSV::Cell removed. A cell is represented as just a String or nil(NULL). This change will cause widespread destruction. CSV.open("foo.csv", "r") do |row| row.each do |cell| if cell.is_null # Cell#is_null p "(NULL)" else p cell.data # Cell#data end end end must be just; CSV.open("foo.csv", "r") do |row| row.each do |cell| if cell.nil? p "(NULL)" else p cell end end end [CAUTION] record separator(CR, LF, CR+LF) behavior change: CSV.open, CSV.parse, and CSV,generate now do not force opened file binmode. Formerly it set binmode explicitly. With CSV.open, binmode of opened file depends the given mode parameter "r", "w", "rb", and "wb". CSV.parse and CSV.generate open file with "r" and "w". Setting mode properly is user's responsibility now. Regards, // NaHi