⚝
One Hat Cyber Team
⚝
Your IP:
216.73.216.13
Server IP:
109.199.105.153
Server:
Linux connect.inboxifs.com 5.15.0-152-generic #162-Ubuntu SMP Wed Jul 23 09:48:42 UTC 2025 x86_64
Server Software:
Apache
PHP Version:
8.2.29
Buat File
|
Buat Folder
Eksekusi
Dir :
~
/
usr
/
share
/
ri
/
3.0.0
/
system
/
CSV
/
Edit File: cdesc-CSV.ri
U:RDoc::NormalClass[iI"CSV:ET@I"Object;To:RDoc::Markup::Document:@parts[o;;[yS:RDoc::Markup::Heading: leveli: textI" \CSV;To:RDoc::Markup::Paragraph;[I"O\CSV (comma-separated variables) data is a text representation of a table:;To:RDoc::Markup::List: @type:BULLET:@items[o:RDoc::Markup::ListItem:@label0;[o;;[I".A _row_ _separator_ delimits table rows. ;TI"CA common row separator is the newline character <tt>"\n"</tt>.;To;;0;[o;;[I"6A _column_ _separator_ delimits fields in a row. ;TI"CA common column separator is the comma character <tt>","</tt>.;To:RDoc::Markup::BlankLine o;;[I"9This \CSV \String, with row separator <tt>"\n"</tt> ;TI"(and column separator <tt>","</tt>, ;TI"$has three rows and two columns:;To:RDoc::Markup::Verbatim;[I""foo,0\nbar,1\nbaz,2\n" ;T:@format0o;;[I"ODespite the name \CSV, a \CSV representation can use different separators.;T@ o;;[ I"6For more about tables, see the Wikipedia article ;TI"Q"{Table (information)}[https://en.wikipedia.org/wiki/Table_(information)]", ;TI"especially its section ;TI"U"{Simple table}[https://en.wikipedia.org/wiki/Table_(information)#Simple_table]";T@ S; ; i;I"\Class \CSV;T@ o;;[I"%Class \CSV provides methods for:;To; ;;;[o;;0;[o;;[I"\Parsing \CSV data from a \String object, a \File (via its file path), or an \IO object.;To;;0;[o;;[I".Generating \CSV data to a \String object.;T@ o;;[I"To make \CSV available:;To;;[I"require 'csv' ;T;0o;;[I"6All examples here assume that this has been done.;T@ S; ; i;I"Keeping It Simple;T@ o;;[I"RA \CSV object has dozens of instance methods that offer fine-grained control ;TI"*of parsing and generating \CSV data. ;TI"8For many needs, though, simpler approaches will do.;T@ o;;[ I";This section summarizes the singleton methods in \CSV ;TI"=that allow you to parse and generate without explicitly ;TI"creating \CSV objects. ;TI"#For details, follow the links.;T@ S; ; i;I"Simple Parsing;T@ o;;[I"/Parsing methods commonly return either of:;To; ;;;[o;;0;[o;;[I"$An \Array of Arrays of Strings:;To; ;;;[o;;0;[o;;[I",The outer \Array is the entire "table".;To;;0;[o;;[I" Each inner \Array is a row.;To;;0;[o;;[I"Each \String is a field.;To;;0;[o;;[I",A CSV::Table object. For details, see ;TI"<{\CSV with Headers}[#class-CSV-label-CSV+with+Headers].;T@ S; ; i ;I"Parsing a \String;T@ o;;[I",The input to be parsed can be a string:;To;;[I"&string = "foo,0\nbar,1\nbaz,2\n" ;T;0o;;[I"4\Method CSV.parse returns the entire \CSV data:;To;;[I"GCSV.parse(string) # => [["foo", "0"], ["bar", "1"], ["baz", "2"]] ;T;0o;;[I"7\Method CSV.parse_line returns only the first row:;To;;[I".CSV.parse_line(string) # => ["foo", "0"] ;T;0o;;[I"G\CSV extends class \String with instance method String#parse_csv, ;TI"+which also returns only the first row:;To;;[I"(string.parse_csv # => ["foo", "0"] ;T;0S; ; i ;I"Parsing Via a \File Path;T@ o;;[I"-The input to be parsed can be in a file:;To;;[I"&string = "foo,0\nbar,1\nbaz,2\n" ;TI"path = 't.csv' ;TI"File.write(path, string) ;T;0o;;[I"3\Method CSV.read returns the entire \CSV data:;To;;[I"DCSV.read(path) # => [["foo", "0"], ["bar", "1"], ["baz", "2"]] ;T;0o;;[I"G\Method CSV.foreach iterates, passing each row to the given block:;To;;[I" CSV.foreach(path) do |row| ;TI" p row ;TI" end ;T;0o;;[I"Output:;To;;[I"["foo", "0"] ;TI"["bar", "1"] ;TI"["baz", "2"] ;T;0o;;[I"K\Method CSV.table returns the entire \CSV data as a CSV::Table object:;To;;[I"DCSV.table(path) # => #<CSV::Table mode:col_or_row row_count:3> ;T;0S; ; i ;I"$Parsing from an Open \IO Stream;T@ o;;[I"9The input to be parsed can be in an open \IO stream:;T@ o;;[I"3\Method CSV.read returns the entire \CSV data:;To;;[I"File.open(path) do |file| ;TI" CSV.read(file) ;TI"9end # => [["foo", "0"], ["bar", "1"], ["baz", "2"]] ;T;0o;;[I"As does method CSV.parse:;To;;[I"File.open(path) do |file| ;TI" CSV.parse(file) ;TI"9end # => [["foo", "0"], ["bar", "1"], ["baz", "2"]] ;T;0o;;[I"7\Method CSV.parse_line returns only the first row:;To;;[I"File.open(path) do |file| ;TI" CSV.parse_line(file) ;TI"end # => ["foo", "0"] ;T;0o;;[I"G\Method CSV.foreach iterates, passing each row to the given block:;To;;[ I"File.open(path) do |file| ;TI"" CSV.foreach(file) do |row| ;TI" p row ;TI" end ;TI" end ;T;0o;;[I"Output:;To;;[I"["foo", "0"] ;TI"["bar", "1"] ;TI"["baz", "2"] ;T;0o;;[I"K\Method CSV.table returns the entire \CSV data as a CSV::Table object:;To;;[I"File.open(path) do |file| ;TI" CSV.table(file) ;TI"8end # => #<CSV::Table mode:col_or_row row_count:3> ;T;0S; ; i;I"Simple Generating;T@ o;;[I"-\Method CSV.generate returns a \String; ;TI"8this example uses method CSV#<< to append the rows ;TI"that are to be generated:;To;;[I"+output_string = CSV.generate do |csv| ;TI" csv << ['foo', 0] ;TI" csv << ['bar', 1] ;TI" csv << ['baz', 2] ;TI" end ;TI"0output_string # => "foo,0\nbar,1\nbaz,2\n" ;T;0o;;[I"K\Method CSV.generate_line returns a \String containing the single row ;TI" constructed from an \Array:;To;;[I"4CSV.generate_line(['foo', '0']) # => "foo,0\n" ;T;0o;;[I"K\CSV extends class \Array with instance method <tt>Array#to_csv</tt>, ;TI"*which forms an \Array into a \String:;To;;[I"(['foo', '0'].to_csv # => "foo,0\n" ;T;0S; ; i;I""Filtering" \CSV;T@ o;;[I"D\Method CSV.filter provides a Unix-style filter for \CSV data. ;TI"9The input data is processed to form the output data:;To;;[I")in_string = "foo,0\nbar,1\nbaz,2\n" ;TI"out_string = '' ;TI"0CSV.filter(in_string, out_string) do |row| ;TI" row[0] = row[0].upcase ;TI" row[1] *= 4 ;TI" end ;TI"6out_string # => "FOO,0000\nBAR,1111\nBAZ,2222\n" ;T;0S; ; i;I"\CSV Objects;T@ o;;[I"2There are three ways to create a \CSV object:;To; ;;;[o;;0;[o;;[I"/\Method CSV.new returns a new \CSV object.;To;;0;[o;;[I">\Method CSV.instance returns a new or cached \CSV object.;To;;0;[o;;[I"=\Method \CSV() also returns a new or cached \CSV object.;T@ S; ; i;I"Instance Methods;T@ o;;[I"/\CSV has three groups of instance methods:;To; ;;;[o;;0;[o;;[I"1Its own internally defined instance methods.;To;;0;[o;;[I"+Methods included by module Enumerable.;To;;0;[o;;[I".Methods delegated to class IO. See below.;T@ S; ; i ;I"Delegated Methods;T@ o;;[I"NFor convenience, a CSV object will delegate to many methods in class IO. ;TI"=(A few have wrapper "guard code" in \CSV.) You may call:;To; ;;;[&o;;0;[o;;[I"IO#binmode;To;;0;[o;;[I"#binmode?;To;;0;[o;;[I" IO#close;To;;0;[o;;[I"IO#close_read;To;;0;[o;;[I"IO#close_write;To;;0;[o;;[I"IO#closed?;To;;0;[o;;[I" #eof;To;;0;[o;;[I" #eof?;To;;0;[o;;[I"IO#external_encoding;To;;0;[o;;[I" IO#fcntl;To;;0;[o;;[I"IO#fileno;To;;0;[o;;[I"#flock;To;;0;[o;;[I" IO#flush;To;;0;[o;;[I" IO#fsync;To;;0;[o;;[I"IO#internal_encoding;To;;0;[o;;[I"#ioctl;To;;0;[o;;[I"IO#isatty;To;;0;[o;;[I" #path;To;;0;[o;;[I"IO#pid;To;;0;[o;;[I"IO#pos;To;;0;[o;;[I"IO#pos=;To;;0;[o;;[I"IO#reopen;To;;0;[o;;[I"#rewind;To;;0;[o;;[I"IO#seek;To;;0;[o;;[I" #stat;To;;0;[o;;[I"IO#string;To;;0;[o;;[I"IO#sync;To;;0;[o;;[I" IO#sync=;To;;0;[o;;[I"IO#tell;To;;0;[o;;[I" #to_i;To;;0;[o;;[I"#to_io;To;;0;[o;;[I"IO#truncate;To;;0;[o;;[I"IO#tty?;T@ S; ; i;I"Options;T@ o;;[I"(The default values for options are:;To;;[I"DEFAULT_OPTIONS = { ;TI"* # For both parsing and generating. ;TI" col_sep: ",", ;TI"" row_sep: :auto, ;TI" quote_char: '"', ;TI" # For parsing. ;TI" field_size_limit: nil, ;TI" converters: nil, ;TI" unconverted_fields: nil, ;TI"" headers: false, ;TI"" return_headers: false, ;TI" header_converters: nil, ;TI"" skip_blanks: false, ;TI" skip_lines: nil, ;TI"" liberal_parsing: false, ;TI" nil_value: nil, ;TI" empty_value: "", ;TI" # For generating. ;TI" write_headers: nil, ;TI"! quote_empty: true, ;TI"" force_quotes: false, ;TI" write_converters: nil, ;TI" write_nil_value: nil, ;TI" write_empty_value: "", ;TI"" strip: false, ;TI"} ;T;0S; ; i ;I"Options for Parsing;T@ o;;[I"=Options for parsing, described in detail below, include:;To; ;;;[o;;0;[o;;[I"B+row_sep+: Specifies the row separator; used to delimit rows.;To;;0;[o;;[I"G+col_sep+: Specifies the column separator; used to delimit fields.;To;;0;[o;;[I"G+quote_char+: Specifies the quote character; used to quote fields.;To;;0;[o;;[I"B+field_size_limit+: Specifies the maximum field size allowed.;To;;0;[o;;[I"=+converters+: Specifies the field converters to be used.;To;;0;[o;;[I"T+unconverted_fields+: Specifies whether unconverted fields are to be available.;To;;0;[o;;[I"9+headers+: Specifies whether data contains headers, ;TI")or specifies the headers themselves.;To;;0;[o;;[I"D+return_headers+: Specifies whether headers are to be returned.;To;;0;[o;;[I"E+header_converters+: Specifies the header converters to be used.;To;;0;[o;;[I"E+skip_blanks+: Specifies whether blanks lines are to be ignored.;To;;0;[o;;[I"E+skip_lines+: Specifies how comments lines are to be recognized.;To;;0;[o;;[I"D+strip+: Specifies whether leading and trailing whitespace are ;TI"!to be stripped from fields..;To;;0;[o;;[I"G+liberal_parsing+: Specifies whether \CSV should attempt to parse ;TI"non-compliant data.;To;;0;[o;;[I"_+nil_value+: Specifies the object that is to be substituted for each null (no-text) field.;To;;0;[o;;[I"X+empty_value+: Specifies the object that is to be substituted for each empty field.;T@ S; ; i;I"Option +row_sep+;T@ o;;[I"WSpecifies the row separator, a \String or the \Symbol <tt>:auto</tt> (see below), ;TI"0to be used for both parsing and generating.;T@ o;;[I"Default value:;To;;[I"5CSV::DEFAULT_OPTIONS.fetch(:row_sep) # => :auto ;T;0S:RDoc::Markup::Rule:weighti@ o;;[I"JWhen +row_sep+ is a \String, that \String becomes the row separator. ;TI"GThe String will be transcoded into the data's Encoding before use.;T@ o;;[I"Using <tt>"\n"</tt>:;To;;[I"row_sep = "\n" ;TI"3str = CSV.generate(row_sep: row_sep) do |csv| ;TI" csv << [:foo, 0] ;TI" csv << [:bar, 1] ;TI" csv << [:baz, 2] ;TI" end ;TI"&str # => "foo,0\nbar,1\nbaz,2\n" ;TI"ary = CSV.parse(str) ;TI"9ary # => [["foo", "0"], ["bar", "1"], ["baz", "2"]] ;T;0o;;[I"Using <tt>|</tt> (pipe):;To;;[I"row_sep = '|' ;TI"3str = CSV.generate(row_sep: row_sep) do |csv| ;TI" csv << [:foo, 0] ;TI" csv << [:bar, 1] ;TI" csv << [:baz, 2] ;TI" end ;TI"#str # => "foo,0|bar,1|baz,2|" ;TI",ary = CSV.parse(str, row_sep: row_sep) ;TI"9ary # => [["foo", "0"], ["bar", "1"], ["baz", "2"]] ;T;0o;;[I"%Using <tt>--</tt> (two hyphens):;To;;[I"row_sep = '--' ;TI"3str = CSV.generate(row_sep: row_sep) do |csv| ;TI" csv << [:foo, 0] ;TI" csv << [:bar, 1] ;TI" csv << [:baz, 2] ;TI" end ;TI"&str # => "foo,0--bar,1--baz,2--" ;TI",ary = CSV.parse(str, row_sep: row_sep) ;TI"9ary # => [["foo", "0"], ["bar", "1"], ["baz", "2"]] ;T;0o;;[I"&Using <tt>''</tt> (empty string):;To;;[I"row_sep = '' ;TI"3str = CSV.generate(row_sep: row_sep) do |csv| ;TI" csv << [:foo, 0] ;TI" csv << [:bar, 1] ;TI" csv << [:baz, 2] ;TI" end ;TI" str # => "foo,0bar,1baz,2" ;TI",ary = CSV.parse(str, row_sep: row_sep) ;TI"-ary # => [["foo", "0bar", "1baz", "2"]] ;T;0S;;i@ o;;[I":When +row_sep+ is the \Symbol +:auto+ (the default), ;TI"8generating uses <tt>"\n"</tt> as the row separator:;To;;[I"!str = CSV.generate do |csv| ;TI" csv << [:foo, 0] ;TI" csv << [:bar, 1] ;TI" csv << [:baz, 2] ;TI" end ;TI"&str # => "foo,0\nbar,1\nbaz,2\n" ;T;0o;;[I"MParsing, on the other hand, invokes auto-discovery of the row separator.;T@ o;;[I"hAuto-discovery reads ahead in the data looking for the next <tt>\r\n</tt>, +\n+, or +\r+ sequence. ;TI"HThe sequence will be selected even if it occurs in a quoted field, ;TI">assuming that you would have the same line endings there.;T@ o;;[I" Example:;To;;[ I"!str = CSV.generate do |csv| ;TI" csv << [:foo, 0] ;TI" csv << [:bar, 1] ;TI" csv << [:baz, 2] ;TI" end ;TI"&str # => "foo,0\nbar,1\nbaz,2\n" ;TI"ary = CSV.parse(str) ;TI"9ary # => [["foo", "0"], ["bar", "1"], ["baz", "2"]] ;T;0o;;[I"HThe default <tt>$INPUT_RECORD_SEPARATOR</tt> (<tt>$/</tt>) is used ;TI"%if any of the following is true:;To; ;;;[o;;0;[o;;[I"&None of those sequences is found.;To;;0;[o;;[I"4Data is +ARGF+, +STDIN+, +STDOUT+, or +STDERR+.;To;;0;[o;;[I"-The stream is only available for output.;T@ o;;[I"-Obviously, discovery takes a little time. Set manually if speed is important. Also note that IO objects should be opened in binary mode on Windows if this feature will be used as the line-ending translation can cause problems with resetting the document position to where it was before the read ahead.;T@ S;;i@ o;;[I"FRaises an exception if the given value is not String-convertible:;To;;[ I"row_sep = BasicObject.new ;TI"J# Raises NoMethodError (undefined method `to_s' for #<BasicObject:>) ;TI")CSV.generate(ary, row_sep: row_sep) ;TI"J# Raises NoMethodError (undefined method `to_s' for #<BasicObject:>) ;TI"&CSV.parse(str, row_sep: row_sep) ;T;0S; ; i;I"Option +col_sep+;T@ o;;[I"6Specifies the \String field separator to be used ;TI"&for both parsing and generating. ;TI"IThe \String will be transcoded into the data's \Encoding before use.;T@ o;;[I"Default value:;To;;[I";CSV::DEFAULT_OPTIONS.fetch(:col_sep) # => "," (comma) ;T;0o;;[I"Using the default (comma):;To;;[ I"!str = CSV.generate do |csv| ;TI" csv << [:foo, 0] ;TI" csv << [:bar, 1] ;TI" csv << [:baz, 2] ;TI" end ;TI"&str # => "foo,0\nbar,1\nbaz,2\n" ;TI"ary = CSV.parse(str) ;TI"9ary # => [["foo", "0"], ["bar", "1"], ["baz", "2"]] ;T;0o;;[I"Using +:+ (colon):;To;;[I"col_sep = ':' ;TI"3str = CSV.generate(col_sep: col_sep) do |csv| ;TI" csv << [:foo, 0] ;TI" csv << [:bar, 1] ;TI" csv << [:baz, 2] ;TI" end ;TI"&str # => "foo:0\nbar:1\nbaz:2\n" ;TI",ary = CSV.parse(str, col_sep: col_sep) ;TI"9ary # => [["foo", "0"], ["bar", "1"], ["baz", "2"]] ;T;0o;;[I"Using +::+ (two colons):;To;;[I"col_sep = '::' ;TI"3str = CSV.generate(col_sep: col_sep) do |csv| ;TI" csv << [:foo, 0] ;TI" csv << [:bar, 1] ;TI" csv << [:baz, 2] ;TI" end ;TI")str # => "foo::0\nbar::1\nbaz::2\n" ;TI",ary = CSV.parse(str, col_sep: col_sep) ;TI"9ary # => [["foo", "0"], ["bar", "1"], ["baz", "2"]] ;T;0o;;[I"&Using <tt>''</tt> (empty string):;To;;[I"col_sep = '' ;TI"3str = CSV.generate(col_sep: col_sep) do |csv| ;TI" csv << [:foo, 0] ;TI" csv << [:bar, 1] ;TI" csv << [:baz, 2] ;TI" end ;TI"#str # => "foo0\nbar1\nbaz2\n" ;T;0S;;i@ o;;[I";Raises an exception if parsing with the empty \String:;To;;[I"col_sep = '' ;TI"H# Raises ArgumentError (:col_sep must be 1 or more characters: "") ;TI"7CSV.parse("foo0\nbar1\nbaz2\n", col_sep: col_sep) ;T;0o;;[I"FRaises an exception if the given value is not String-convertible:;To;;[ I"col_sep = BasicObject.new ;TI"J# Raises NoMethodError (undefined method `to_s' for #<BasicObject:>) ;TI"*CSV.generate(line, col_sep: col_sep) ;TI"J# Raises NoMethodError (undefined method `to_s' for #<BasicObject:>) ;TI"&CSV.parse(str, col_sep: col_sep) ;T;0S; ; i;I"Option +quote_char+;T@ o;;[I"MSpecifies the character (\String of length 1) used used to quote fields ;TI"%in both parsing and generating. ;TI"IThis String will be transcoded into the data's \Encoding before use.;T@ o;;[I"Default value:;To;;[I"FCSV::DEFAULT_OPTIONS.fetch(:quote_char) # => "\"" (double quote) ;T;0o;;[I"WThis is useful for an application that incorrectly uses <tt>'</tt> (single-quote) ;TI"Gto quote fields, instead of the correct <tt>"</tt> (double-quote).;T@ o;;[I"&Using the default (double quote):;To;;[ I"!str = CSV.generate do |csv| ;TI" csv << ['foo', 0] ;TI" csv << ["'bar'", 1] ;TI" csv << ['"baz"', 2] ;TI" end ;TI"4str # => "foo,0\n'bar',1\n\"\"\"baz\"\"\",2\n" ;TI"ary = CSV.parse(str) ;TI"?ary # => [["foo", "0"], ["'bar'", "1"], ["\"baz\"", "2"]] ;T;0o;;[I"%Using <tt>'</tt> (single-quote):;To;;[I"quote_char = "'" ;TI"9str = CSV.generate(quote_char: quote_char) do |csv| ;TI" csv << ['foo', 0] ;TI" csv << ["'bar'", 1] ;TI" csv << ['"baz"', 2] ;TI" end ;TI"0str # => "foo,0\n'''bar''',1\n\"baz\",2\n" ;TI"2ary = CSV.parse(str, quote_char: quote_char) ;TI"?ary # => [["foo", "0"], ["'bar'", "1"], ["\"baz\"", "2"]] ;T;0S;;i@ o;;[I"ARaises an exception if the \String length is greater than 1:;To;;[I"U# Raises ArgumentError (:quote_char has to be nil or a single character String) ;TI"#CSV.new('', quote_char: 'xx') ;T;0o;;[I"7Raises an exception if the value is not a \String:;To;;[I"U# Raises ArgumentError (:quote_char has to be nil or a single character String) ;TI"#CSV.new('', quote_char: :foo) ;T;0S; ; i;I"Option +field_size_limit+;T@ o;;[I"-Specifies the \Integer field size limit.;T@ o;;[I"Default value:;To;;[I"<CSV::DEFAULT_OPTIONS.fetch(:field_size_limit) # => nil ;T;0o;;[I"[This is a maximum size CSV will read ahead looking for the closing quote for a field. ;TI"E(In truth, it reads to the first line ending beyond this size.) ;TI"UIf a quote cannot be found within the limit CSV will raise a MalformedCSVError, ;TI""assuming the data is faulty. ;TI"WYou can use this limit to prevent what are effectively DoS attacks on the parser. ;TI"?However, this limit can cause a legitimate parse to fail; ;TI"5therefore the default value is +nil+ (no limit).;T@ o;;[I"&For the examples in this section:;To;;[I"str = <<~EOT ;TI" "a","b" ;TI" " ;TI" 2345 ;TI" ","" ;TI" EOT ;TI"1str # => "\"a\",\"b\"\n\"\n2345\n\",\"\"\n" ;T;0o;;[I"Using the default +nil+:;To;;[I"ary = CSV.parse(str) ;TI"-ary # => [["a", "b"], ["\n2345\n", ""]] ;T;0o;;[I"Using <tt>50</tt>:;To;;[I"field_size_limit = 50 ;TI">ary = CSV.parse(str, field_size_limit: field_size_limit) ;TI"-ary # => [["a", "b"], ["\n2345\n", ""]] ;T;0S;;i@ o;;[I"0Raises an exception if a field is too long:;To;;[I"$big_str = "123456789\n" * 1024 ;TI"F# Raises CSV::MalformedCSVError (Field size exceeded in line 1.) ;TI"ICSV.parse('valid,fields,"' + big_str + '"', field_size_limit: 2048) ;T;0S; ; i;I"Option +converters+;T@ o;;[I"8Specifies converters to be used in parsing fields. ;TI">See {Field Converters}[#class-CSV-label-Field+Converters];T@ o;;[I"Default value:;To;;[I"6CSV::DEFAULT_OPTIONS.fetch(:converters) # => nil ;T;0o;;[I"-The value may be a field converter name ;TI"C(see {Stored Converters}[#class-CSV-label-Stored+Converters]):;To;;[I"str = '1,2,3' ;TI"# Without a converter ;TI"!array = CSV.parse_line(str) ;TI" array # => ["1", "2", "3"] ;TI"(# With built-in converter :integer ;TI"7array = CSV.parse_line(str, converters: :integer) ;TI"array # => [1, 2, 3] ;T;0o;;[I"'The value may be a converter list ;TI"?(see {Converter Lists}[#class-CSV-label-Converter+Lists]):;To;;[I"str = '1,3.14159' ;TI"# Without converters ;TI"!array = CSV.parse_line(str) ;TI"!array # => ["1", "3.14159"] ;TI" # With built-in converters ;TI"Aarray = CSV.parse_line(str, converters: [:integer, :float]) ;TI"array # => [1, 3.14159] ;T;0o;;[I"0The value may be a \Proc custom converter: ;TI"O(see {Custom Field Converters}[#class-CSV-label-Custom+Field+Converters]):;To;;[I"$str = ' foo , bar , baz ' ;TI"# Without a converter ;TI"!array = CSV.parse_line(str) ;TI"1array # => [" foo ", " bar ", " baz "] ;TI"# With a custom converter ;TI"Jarray = CSV.parse_line(str, converters: proc {|field| field.strip }) ;TI"&array # => ["foo", "bar", "baz"] ;T;0o;;[I"QSee also {Custom Field Converters}[#class-CSV-label-Custom+Field+Converters];T@ S;;i@ o;;[I"MRaises an exception if the converter is not a converter name or a \Proc:;To;;[I"str = 'foo,0' ;TI"H# Raises NoMethodError (undefined method `arity' for nil:NilClass) ;TI"&CSV.parse(str, converters: :foo) ;T;0S; ; i;I" Option +unconverted_fields+;T@ o;;[I"`Specifies the boolean that determines whether unconverted field values are to be available.;T@ o;;[I"Default value:;To;;[I">CSV::DEFAULT_OPTIONS.fetch(:unconverted_fields) # => nil ;T;0o;;[I"FThe unconverted field values are those found in the source data, ;TI"@prior to any conversions performed via option +converters+.;T@ o;;[I"1When option +unconverted_fields+ is +true+, ;TI"Beach returned row (\Array or \CSV::Row) has an added method, ;TI"E+unconverted_fields+, that returns the unconverted field values:;To;;[I"str = <<-EOT ;TI"foo,0 ;TI"bar,1 ;TI"baz,2 ;TI" EOT ;TI""# Without unconverted_fields ;TI"0csv = CSV.parse(str, converters: :integer) ;TI"3csv # => [["foo", 0], ["bar", 1], ["baz", 2]] ;TI";csv.first.respond_to?(:unconverted_fields) # => false ;TI"# With unconverted_fields ;TI"Jcsv = CSV.parse(str, converters: :integer, unconverted_fields: true) ;TI"3csv # => [["foo", 0], ["bar", 1], ["baz", 2]] ;TI":csv.first.respond_to?(:unconverted_fields) # => true ;TI"4csv.first.unconverted_fields # => ["foo", "0"] ;T;0S; ; i;I"Option +headers+;T@ o;;[I"ASpecifies a boolean, \Symbol, \Array, or \String to be used ;TI"to define column headers.;T@ o;;[I"Default value:;To;;[I"5CSV::DEFAULT_OPTIONS.fetch(:headers) # => false ;T;0S;;i@ o;;[I"Without +headers+:;To;;[I"str = <<-EOT ;TI"Name,Count ;TI"foo,0 ;TI"bar,1 ;TI"bax,2 ;TI" EOT ;TI"csv = CSV.new(str) ;TI"gcsv # => #<CSV io_type:StringIO encoding:UTF-8 lineno:0 col_sep:"," row_sep:"\n" quote_char:"\""> ;TI"csv.headers # => nil ;TI"&csv.shift # => ["Name", "Count"] ;T;0S;;i@ o;;[I"3If set to +true+ or the \Symbol +:first_row+, ;TI">the first row of the data is treated as a row of headers:;To;;[I"str = <<-EOT ;TI"Name,Count ;TI"foo,0 ;TI"bar,1 ;TI"bax,2 ;TI" EOT ;TI"'csv = CSV.new(str, headers: true) ;TI"|csv # => #<CSV io_type:StringIO encoding:UTF-8 lineno:2 col_sep:"," row_sep:"\n" quote_char:"\"" headers:["Name", "Count"]> ;TI"(csv.headers # => ["Name", "Count"] ;TI"9csv.shift # => #<CSV::Row "Name":"bar" "Count":"1"> ;T;0S;;i@ o;;[I"EIf set to an \Array, the \Array elements are treated as headers:;To;;[I"str = <<-EOT ;TI"foo,0 ;TI"bar,1 ;TI"bax,2 ;TI" EOT ;TI"4csv = CSV.new(str, headers: ['Name', 'Count']) ;TI" csv ;TI"(csv.headers # => ["Name", "Count"] ;TI"9csv.shift # => #<CSV::Row "Name":"bar" "Count":"1"> ;T;0S;;i@ o;;[I"XIf set to a \String +str+, method <tt>CSV::parse_line(str, options)</tt> is called ;TI"Owith the current +options+, and the returned \Array is treated as headers:;To;;[I"str = <<-EOT ;TI"foo,0 ;TI"bar,1 ;TI"bax,2 ;TI" EOT ;TI"/csv = CSV.new(str, headers: 'Name,Count') ;TI" csv ;TI"(csv.headers # => ["Name", "Count"] ;TI"9csv.shift # => #<CSV::Row "Name":"bar" "Count":"1"> ;T;0S; ; i;I"Option +return_headers+;T@ o;;[I"ASpecifies the boolean that determines whether method #shift ;TI"'returns or ignores the header row.;T@ o;;[I"Default value:;To;;[I"<CSV::DEFAULT_OPTIONS.fetch(:return_headers) # => false ;T;0o;;[I"Examples:;To;;[I"str = <<-EOT ;TI"Name,Count ;TI"foo,0 ;TI"bar,1 ;TI"bax,2 ;TI" EOT ;TI"0# Without return_headers first row is str. ;TI"'csv = CSV.new(str, headers: true) ;TI"9csv.shift # => #<CSV::Row "Name":"foo" "Count":"0"> ;TI"1# With return_headers first row is headers. ;TI"=csv = CSV.new(str, headers: true, return_headers: true) ;TI">csv.shift # => #<CSV::Row "Name":"Name" "Count":"Count"> ;T;0S; ; i;I"Option +header_converters+;T@ o;;[I"9Specifies converters to be used in parsing headers. ;TI"@See {Header Converters}[#class-CSV-label-Header+Converters];T@ o;;[I"Default value:;To;;[I"=CSV::DEFAULT_OPTIONS.fetch(:header_converters) # => nil ;T;0o;;[I"[Identical in functionality to option {converters}[#class-CSV-label-Option+converters] ;TI"except that:;To; ;;;[o;;0;[o;;[I"1The converters apply only to the header row.;To;;0;[o;;[I"BThe built-in header converters are +:downcase+ and +:symbol+.;T@ o;;[I"-This section assumes prior execution of:;To;;[I"str = <<-EOT ;TI"Name,Value ;TI"foo,0 ;TI"bar,1 ;TI"baz,2 ;TI" EOT ;TI" # With no header converter ;TI"+table = CSV.parse(str, headers: true) ;TI"*table.headers # => ["Name", "Value"] ;T;0o;;[I".The value may be a header converter name ;TI"C(see {Stored Converters}[#class-CSV-label-Stored+Converters]):;To;;[I"Itable = CSV.parse(str, headers: true, header_converters: :downcase) ;TI"*table.headers # => ["name", "value"] ;T;0o;;[I"'The value may be a converter list ;TI"?(see {Converter Lists}[#class-CSV-label-Converter+Lists]):;To;;[I".header_converters = [:downcase, :symbol] ;TI"Qtable = CSV.parse(str, headers: true, header_converters: header_converters) ;TI"(table.headers # => [:name, :value] ;T;0o;;[I"/The value may be a \Proc custom converter ;TI"Q(see {Custom Header Converters}[#class-CSV-label-Custom+Header+Converters]):;To;;[I"5upcase_converter = proc {|field| field.upcase } ;TI"Ptable = CSV.parse(str, headers: true, header_converters: upcase_converter) ;TI"*table.headers # => ["NAME", "VALUE"] ;T;0o;;[I"SSee also {Custom Header Converters}[#class-CSV-label-Custom+Header+Converters];T@ S; ; i;I"Option +skip_blanks+;T@ o;;[I"[Specifies a boolean that determines whether blank lines in the input will be ignored; ;TI"Ka line that contains a column separator is not considered to be blank.;T@ o;;[I"Default value:;To;;[I"9CSV::DEFAULT_OPTIONS.fetch(:skip_blanks) # => false ;T;0o;;[I"ESee also option {skiplines}[#class-CSV-label-Option+skip_lines].;T@ o;;[I""For examples in this section:;To;;[ I"str = <<-EOT ;TI"foo,0 ;TI" ;TI"bar,1 ;TI"baz,2 ;TI" ;TI", ;TI" EOT ;T;0o;;[I" Using the default, +false+:;To;;[I"ary = CSV.parse(str) ;TI"Mary # => [["foo", "0"], [], ["bar", "1"], ["baz", "2"], [], [nil, nil]] ;T;0o;;[I"Using +true+:;To;;[I"-ary = CSV.parse(str, skip_blanks: true) ;TI"Eary # => [["foo", "0"], ["bar", "1"], ["baz", "2"], [nil, nil]] ;T;0o;;[I"Using a truthy value:;To;;[I"-ary = CSV.parse(str, skip_blanks: :foo) ;TI"Eary # => [["foo", "0"], ["bar", "1"], ["baz", "2"], [nil, nil]] ;T;0S; ; i;I"Option +skip_lines+;T@ o;;[I"aSpecifies an object to use in identifying comment lines in the input that are to be ignored:;To; ;;;[o;;0;[o;;[I"/If a \Regexp, ignores lines that match it.;To;;0;[o;;[I"IIf a \String, converts it to a \Regexp, ignores lines that match it.;To;;0;[o;;[I"6If +nil+, no lines are considered to be comments.;T@ o;;[I"Default value:;To;;[I"6CSV::DEFAULT_OPTIONS.fetch(:skip_lines) # => nil ;T;0o;;[I""For examples in this section:;To;;[ I"str = <<-EOT ;TI"# Comment ;TI"foo,0 ;TI"bar,1 ;TI"baz,2 ;TI"# Another comment ;TI" EOT ;TI"Dstr # => "# Comment\nfoo,0\nbar,1\nbaz,2\n# Another comment\n" ;T;0o;;[I"Using the default, +nil+:;To;;[I"ary = CSV.parse(str) ;TI"_ary # => [["# Comment"], ["foo", "0"], ["bar", "1"], ["baz", "2"], ["# Another comment"]] ;T;0o;;[I"Using a \Regexp:;To;;[I",ary = CSV.parse(str, skip_lines: /^#/) ;TI"9ary # => [["foo", "0"], ["bar", "1"], ["baz", "2"]] ;T;0o;;[I"Using a \String:;To;;[I"+ary = CSV.parse(str, skip_lines: '#') ;TI"9ary # => [["foo", "0"], ["bar", "1"], ["baz", "2"]] ;T;0S;;i@ o;;[I"WRaises an exception if given an object that is not a \Regexp, a \String, or +nil+:;To;;[I"F# Raises ArgumentError (:skip_lines has to respond to #match: 0) ;TI"#CSV.parse(str, skip_lines: 0) ;T;0S; ; i;I"Option +strip+;T@ o;;[I"9Specifies the boolean value that determines whether ;TI"2whitespace is stripped from each input field.;T@ o;;[I"Default value:;To;;[I"3CSV::DEFAULT_OPTIONS.fetch(:strip) # => false ;T;0o;;[I" With default value +false+:;To;;[I"%ary = CSV.parse_line(' a , b ') ;TI"ary # => [" a ", " b "] ;T;0o;;[I"With value +true+:;To;;[I"2ary = CSV.parse_line(' a , b ', strip: true) ;TI"ary # => ["a", "b"] ;T;0S; ; i;I"Option +liberal_parsing+;T@ o;;[I"9Specifies the boolean value that determines whether ;TI"CCSV will attempt to parse input not conformant with RFC 4180, ;TI".such as double quotes in unquoted fields.;T@ o;;[I"Default value:;To;;[I"=CSV::DEFAULT_OPTIONS.fetch(:liberal_parsing) # => false ;T;0o;;[I""For examples in this section:;To;;[I"-str = 'is,this "three, or four",fields' ;T;0o;;[I"Without +liberal_parsing+:;To;;[I"A# Raises CSV::MalformedCSVError (Illegal quoting in str 1.) ;TI"CSV.parse_line(str) ;T;0o;;[I"With +liberal_parsing+:;To;;[I"6ary = CSV.parse_line(str, liberal_parsing: true) ;TI"=ary # => ["is", "this \"three", " or four\"", "fields"] ;T;0S; ; i;I"Option +nil_value+;T@ o;;[I"RSpecifies the object that is to be substituted for each null (no-text) field.;T@ o;;[I"Default value:;To;;[I"5CSV::DEFAULT_OPTIONS.fetch(:nil_value) # => nil ;T;0o;;[I"With the default, +nil+:;To;;[I">CSV.parse_line('a,,b,,c') # => ["a", nil, "b", nil, "c"] ;T;0o;;[I"With a different object:;To;;[I"HCSV.parse_line('a,,b,,c', nil_value: 0) # => ["a", 0, "b", 0, "c"] ;T;0S; ; i;I"Option +empty_value+;T@ o;;[I"4Specifies the object that is to be substituted ;TI".for each field that has an empty \String.;T@ o;;[I"Default value:;To;;[I"ECSV::DEFAULT_OPTIONS.fetch(:empty_value) # => "" (empty string) ;T;0o;;[I"#With the default, <tt>""</tt>:;To;;[I"@CSV.parse_line('a,"",b,"",c') # => ["a", "", "b", "", "c"] ;T;0o;;[I"With a different object:;To;;[I"TCSV.parse_line('a,"",b,"",c', empty_value: 'x') # => ["a", "x", "b", "x", "c"] ;T;0S; ; i ;I"Options for Generating;T@ o;;[I"@Options for generating, described in detail below, include:;To; ;;;[o;;0;[o;;[I"B+row_sep+: Specifies the row separator; used to delimit rows.;To;;0;[o;;[I"G+col_sep+: Specifies the column separator; used to delimit fields.;To;;0;[o;;[I"G+quote_char+: Specifies the quote character; used to quote fields.;To;;0;[o;;[I"B+write_headers+: Specifies whether headers are to be written.;To;;0;[o;;[I"I+force_quotes+: Specifies whether each output field is to be quoted.;To;;0;[o;;[I"N+quote_empty+: Specifies whether each empty output field is to be quoted.;To;;0;[o;;[I"N+write_converters+: Specifies the field converters to be used in writing.;To;;0;[o;;[I"c+write_nil_value+: Specifies the object that is to be substituted for each +nil+-valued field.;To;;0;[o;;[I"^+write_empty_value+: Specifies the object that is to be substituted for each empty field.;T@ S; ; i;I"Option +row_sep+;T@ o;;[I"WSpecifies the row separator, a \String or the \Symbol <tt>:auto</tt> (see below), ;TI"0to be used for both parsing and generating.;T@ o;;[I"Default value:;To;;[I"5CSV::DEFAULT_OPTIONS.fetch(:row_sep) # => :auto ;T;0S;;i@ o;;[I"JWhen +row_sep+ is a \String, that \String becomes the row separator. ;TI"GThe String will be transcoded into the data's Encoding before use.;T@ o;;[I"Using <tt>"\n"</tt>:;To;;[I"row_sep = "\n" ;TI"3str = CSV.generate(row_sep: row_sep) do |csv| ;TI" csv << [:foo, 0] ;TI" csv << [:bar, 1] ;TI" csv << [:baz, 2] ;TI" end ;TI"&str # => "foo,0\nbar,1\nbaz,2\n" ;TI"ary = CSV.parse(str) ;TI"9ary # => [["foo", "0"], ["bar", "1"], ["baz", "2"]] ;T;0o;;[I"Using <tt>|</tt> (pipe):;To;;[I"row_sep = '|' ;TI"3str = CSV.generate(row_sep: row_sep) do |csv| ;TI" csv << [:foo, 0] ;TI" csv << [:bar, 1] ;TI" csv << [:baz, 2] ;TI" end ;TI"#str # => "foo,0|bar,1|baz,2|" ;TI",ary = CSV.parse(str, row_sep: row_sep) ;TI"9ary # => [["foo", "0"], ["bar", "1"], ["baz", "2"]] ;T;0o;;[I"%Using <tt>--</tt> (two hyphens):;To;;[I"row_sep = '--' ;TI"3str = CSV.generate(row_sep: row_sep) do |csv| ;TI" csv << [:foo, 0] ;TI" csv << [:bar, 1] ;TI" csv << [:baz, 2] ;TI" end ;TI"&str # => "foo,0--bar,1--baz,2--" ;TI",ary = CSV.parse(str, row_sep: row_sep) ;TI"9ary # => [["foo", "0"], ["bar", "1"], ["baz", "2"]] ;T;0o;;[I"&Using <tt>''</tt> (empty string):;To;;[I"row_sep = '' ;TI"3str = CSV.generate(row_sep: row_sep) do |csv| ;TI" csv << [:foo, 0] ;TI" csv << [:bar, 1] ;TI" csv << [:baz, 2] ;TI" end ;TI" str # => "foo,0bar,1baz,2" ;TI",ary = CSV.parse(str, row_sep: row_sep) ;TI"-ary # => [["foo", "0bar", "1baz", "2"]] ;T;0S;;i@ o;;[I":When +row_sep+ is the \Symbol +:auto+ (the default), ;TI"8generating uses <tt>"\n"</tt> as the row separator:;To;;[I"!str = CSV.generate do |csv| ;TI" csv << [:foo, 0] ;TI" csv << [:bar, 1] ;TI" csv << [:baz, 2] ;TI" end ;TI"&str # => "foo,0\nbar,1\nbaz,2\n" ;T;0o;;[I"MParsing, on the other hand, invokes auto-discovery of the row separator.;T@ o;;[I"hAuto-discovery reads ahead in the data looking for the next <tt>\r\n</tt>, +\n+, or +\r+ sequence. ;TI"HThe sequence will be selected even if it occurs in a quoted field, ;TI">assuming that you would have the same line endings there.;T@ o;;[I" Example:;To;;[ I"!str = CSV.generate do |csv| ;TI" csv << [:foo, 0] ;TI" csv << [:bar, 1] ;TI" csv << [:baz, 2] ;TI" end ;TI"&str # => "foo,0\nbar,1\nbaz,2\n" ;TI"ary = CSV.parse(str) ;TI"9ary # => [["foo", "0"], ["bar", "1"], ["baz", "2"]] ;T;0o;;[I"HThe default <tt>$INPUT_RECORD_SEPARATOR</tt> (<tt>$/</tt>) is used ;TI"%if any of the following is true:;To; ;;;[o;;0;[o;;[I"&None of those sequences is found.;To;;0;[o;;[I"4Data is +ARGF+, +STDIN+, +STDOUT+, or +STDERR+.;To;;0;[o;;[I"-The stream is only available for output.;T@ o;;[I"-Obviously, discovery takes a little time. Set manually if speed is important. Also note that IO objects should be opened in binary mode on Windows if this feature will be used as the line-ending translation can cause problems with resetting the document position to where it was before the read ahead.;T@ S;;i@ o;;[I"FRaises an exception if the given value is not String-convertible:;To;;[ I"row_sep = BasicObject.new ;TI"J# Raises NoMethodError (undefined method `to_s' for #<BasicObject:>) ;TI")CSV.generate(ary, row_sep: row_sep) ;TI"J# Raises NoMethodError (undefined method `to_s' for #<BasicObject:>) ;TI"&CSV.parse(str, row_sep: row_sep) ;T;0S; ; i;I"Option +col_sep+;T@ o;;[I"6Specifies the \String field separator to be used ;TI"&for both parsing and generating. ;TI"IThe \String will be transcoded into the data's \Encoding before use.;T@ o;;[I"Default value:;To;;[I";CSV::DEFAULT_OPTIONS.fetch(:col_sep) # => "," (comma) ;T;0o;;[I"Using the default (comma):;To;;[ I"!str = CSV.generate do |csv| ;TI" csv << [:foo, 0] ;TI" csv << [:bar, 1] ;TI" csv << [:baz, 2] ;TI" end ;TI"&str # => "foo,0\nbar,1\nbaz,2\n" ;TI"ary = CSV.parse(str) ;TI"9ary # => [["foo", "0"], ["bar", "1"], ["baz", "2"]] ;T;0o;;[I"Using +:+ (colon):;To;;[I"col_sep = ':' ;TI"3str = CSV.generate(col_sep: col_sep) do |csv| ;TI" csv << [:foo, 0] ;TI" csv << [:bar, 1] ;TI" csv << [:baz, 2] ;TI" end ;TI"&str # => "foo:0\nbar:1\nbaz:2\n" ;TI",ary = CSV.parse(str, col_sep: col_sep) ;TI"9ary # => [["foo", "0"], ["bar", "1"], ["baz", "2"]] ;T;0o;;[I"Using +::+ (two colons):;To;;[I"col_sep = '::' ;TI"3str = CSV.generate(col_sep: col_sep) do |csv| ;TI" csv << [:foo, 0] ;TI" csv << [:bar, 1] ;TI" csv << [:baz, 2] ;TI" end ;TI")str # => "foo::0\nbar::1\nbaz::2\n" ;TI",ary = CSV.parse(str, col_sep: col_sep) ;TI"9ary # => [["foo", "0"], ["bar", "1"], ["baz", "2"]] ;T;0o;;[I"&Using <tt>''</tt> (empty string):;To;;[I"col_sep = '' ;TI"3str = CSV.generate(col_sep: col_sep) do |csv| ;TI" csv << [:foo, 0] ;TI" csv << [:bar, 1] ;TI" csv << [:baz, 2] ;TI" end ;TI"#str # => "foo0\nbar1\nbaz2\n" ;T;0S;;i@ o;;[I";Raises an exception if parsing with the empty \String:;To;;[I"col_sep = '' ;TI"H# Raises ArgumentError (:col_sep must be 1 or more characters: "") ;TI"7CSV.parse("foo0\nbar1\nbaz2\n", col_sep: col_sep) ;T;0o;;[I"FRaises an exception if the given value is not String-convertible:;To;;[ I"col_sep = BasicObject.new ;TI"J# Raises NoMethodError (undefined method `to_s' for #<BasicObject:>) ;TI"*CSV.generate(line, col_sep: col_sep) ;TI"J# Raises NoMethodError (undefined method `to_s' for #<BasicObject:>) ;TI"&CSV.parse(str, col_sep: col_sep) ;T;0S; ; i;I"Option +quote_char+;T@ o;;[I"MSpecifies the character (\String of length 1) used used to quote fields ;TI"%in both parsing and generating. ;TI"IThis String will be transcoded into the data's \Encoding before use.;T@ o;;[I"Default value:;To;;[I"FCSV::DEFAULT_OPTIONS.fetch(:quote_char) # => "\"" (double quote) ;T;0o;;[I"WThis is useful for an application that incorrectly uses <tt>'</tt> (single-quote) ;TI"Gto quote fields, instead of the correct <tt>"</tt> (double-quote).;T@ o;;[I"&Using the default (double quote):;To;;[ I"!str = CSV.generate do |csv| ;TI" csv << ['foo', 0] ;TI" csv << ["'bar'", 1] ;TI" csv << ['"baz"', 2] ;TI" end ;TI"4str # => "foo,0\n'bar',1\n\"\"\"baz\"\"\",2\n" ;TI"ary = CSV.parse(str) ;TI"?ary # => [["foo", "0"], ["'bar'", "1"], ["\"baz\"", "2"]] ;T;0o;;[I"%Using <tt>'</tt> (single-quote):;To;;[I"quote_char = "'" ;TI"9str = CSV.generate(quote_char: quote_char) do |csv| ;TI" csv << ['foo', 0] ;TI" csv << ["'bar'", 1] ;TI" csv << ['"baz"', 2] ;TI" end ;TI"0str # => "foo,0\n'''bar''',1\n\"baz\",2\n" ;TI"2ary = CSV.parse(str, quote_char: quote_char) ;TI"?ary # => [["foo", "0"], ["'bar'", "1"], ["\"baz\"", "2"]] ;T;0S;;i@ o;;[I"ARaises an exception if the \String length is greater than 1:;To;;[I"U# Raises ArgumentError (:quote_char has to be nil or a single character String) ;TI"#CSV.new('', quote_char: 'xx') ;T;0o;;[I"7Raises an exception if the value is not a \String:;To;;[I"U# Raises ArgumentError (:quote_char has to be nil or a single character String) ;TI"#CSV.new('', quote_char: :foo) ;T;0S; ; i;I"Option +write_headers+;T@ o;;[I"[Specifies the boolean that determines whether a header row is included in the output; ;TI"%ignored if there are no headers.;T@ o;;[I"Default value:;To;;[I"9CSV::DEFAULT_OPTIONS.fetch(:write_headers) # => nil ;T;0o;;[I"Without +write_headers+:;To;;[I"file_path = 't.csv' ;TI"CSV.open(file_path,'w', ;TI"& :headers => ['Name','Value'] ;TI" ) do |csv| ;TI" csv << ['foo', '0'] ;TI" end ;TI""CSV.open(file_path) do |csv| ;TI" csv.shift ;TI"end # => ["foo", "0"] ;T;0o;;[I"With +write_headers+":;To;;[I"CSV.open(file_path,'w', ;TI" :write_headers=> true, ;TI"& :headers => ['Name','Value'] ;TI" ) do |csv| ;TI" csv << ['foo', '0'] ;TI" end ;TI""CSV.open(file_path) do |csv| ;TI" csv.shift ;TI" end # => ["Name", "Value"] ;T;0S; ; i;I"Option +force_quotes+;T@ o;;[I"\Specifies the boolean that determines whether each output field is to be double-quoted.;T@ o;;[I"Default value:;To;;[I":CSV::DEFAULT_OPTIONS.fetch(:force_quotes) # => false ;T;0o;;[I""For examples in this section:;To;;[I"ary = ['foo', 0, nil] ;T;0o;;[I" Using the default, +false+:;To;;[I""str = CSV.generate_line(ary) ;TI"str # => "foo,0,\n" ;T;0o;;[I"Using +true+:;To;;[I"6str = CSV.generate_line(ary, force_quotes: true) ;TI"%str # => "\"foo\",\"0\",\"\"\n" ;T;0S; ; i;I"Option +quote_empty+;T@ o;;[I"YSpecifies the boolean that determines whether an empty value is to be double-quoted.;T@ o;;[I"Default value:;To;;[I"8CSV::DEFAULT_OPTIONS.fetch(:quote_empty) # => true ;T;0o;;[I"With the default +true+:;To;;[I"9CSV.generate_line(['"', ""]) # => "\"\"\"\",\"\"\n" ;T;0o;;[I"With +false+:;To;;[I"ICSV.generate_line(['"', ""], quote_empty: false) # => "\"\"\"\",\n" ;T;0S; ; i;I"Option +write_converters+;T@ o;;[I";Specifies converters to be used in generating fields. ;TI">See {Write Converters}[#class-CSV-label-Write+Converters];T@ o;;[I"Default value:;To;;[I"<CSV::DEFAULT_OPTIONS.fetch(:write_converters) # => nil ;T;0o;;[I"With no write converter:;To;;[I"8str = CSV.generate_line(["\na\n", "\tb\t", " c "]) ;TI"&str # => "\"\na\n\",\tb\t, c \n" ;T;0o;;[I"With a write converter:;To;;[I"3strip_converter = proc {|field| field.strip } ;TI"[str = CSV.generate_line(["\na\n", "\tb\t", " c "], write_converters: strip_converter) ;TI"str # => "a,b,c\n" ;T;0o;;[I"1With two write converters (called in order):;To;;[ I"5upcase_converter = proc {|field| field.upcase } ;TI"9downcase_converter = proc {|field| field.downcase } ;TI"?write_converters = [upcase_converter, downcase_converter] ;TI"Rstr = CSV.generate_line(['a', 'b', 'c'], write_converters: write_converters) ;TI"str # => "a,b,c\n" ;T;0o;;[I"CSee also {Write Converters}[#class-CSV-label-Write+Converters];T@ S;;i@ o;;[I"PRaises an exception if the converter returns a value that is neither +nil+ ;TI"nor \String-convertible:;To;;[I"5bad_converter = proc {|field| BasicObject.new } ;TI"K# Raises NoMethodError (undefined method `is_a?' for #<BasicObject:>) ;TI"JCSV.generate_line(['a', 'b', 'c'], write_converters: bad_converter)# ;T;0S; ; i;I"Option +write_nil_value+;T@ o;;[I"PSpecifies the object that is to be substituted for each +nil+-valued field.;T@ o;;[I"Default value:;To;;[I";CSV::DEFAULT_OPTIONS.fetch(:write_nil_value) # => nil ;T;0o;;[I"Without the option:;To;;[I"3str = CSV.generate_line(['a', nil, 'c', nil]) ;TI"str # => "a,,c,\n" ;T;0o;;[I"With the option:;To;;[I"Istr = CSV.generate_line(['a', nil, 'c', nil], write_nil_value: "x") ;TI"str # => "a,x,c,x\n" ;T;0S; ; i;I"Option +write_empty_value+;T@ o;;[I"CSpecifies the object that is to be substituted for each field ;TI"that has an empty \String.;T@ o;;[I"Default value:;To;;[I"<CSV::DEFAULT_OPTIONS.fetch(:write_empty_value) # => "" ;T;0o;;[I"Without the option:;To;;[I"1str = CSV.generate_line(['a', '', 'c', '']) ;TI" str # => "a,\"\",c,\"\"\n" ;T;0o;;[I"With the option:;To;;[I"Istr = CSV.generate_line(['a', '', 'c', ''], write_empty_value: "x") ;TI"str # => "a,x,c,x\n" ;T;0S; ; i;I"\CSV with Headers;T@ o;;[I"RCSV allows to specify column names of CSV file, whether they are in data, or ;TI"Wprovided separately. If headers are specified, reading methods return an instance ;TI"+of CSV::Table, consisting of CSV::Row.;T@ o;;[I" # Headers are part of data ;TI".data = CSV.parse(<<~ROWS, headers: true) ;TI" Name,Department,Salary ;TI" Bob,Engineering,1000 ;TI" Jane,Sales,2000 ;TI" John,Management,5000 ;TI" ROWS ;TI" ;TI"$data.class #=> CSV::Table ;TI"]data.first #=> #<CSV::Row "Name":"Bob" "Department":"Engineering" "Salary":"1000"> ;TI"Xdata.first.to_h #=> {"Name"=>"Bob", "Department"=>"Engineering", "Salary"=>"1000"} ;TI" ;TI"%# Headers provided by developer ;TI"Sdata = CSV.parse('Bob,Engineering,1000', headers: %i[name department salary]) ;TI"Wdata.first #=> #<CSV::Row name:"Bob" department:"Engineering" salary:"1000"> ;T;0S; ; i;I"\Converters;T@ o;;[I"WBy default, each value (field or header) parsed by \CSV is formed into a \String. ;TI"@You can use a _field_ _converter_ or _header_ _converter_ ;TI"/to intercept and modify the parsed values:;To; ;;;[o;;0;[o;;[I"?See {Field Converters}[#class-CSV-label-Field+Converters].;To;;0;[o;;[I"ASee {Header Converters}[#class-CSV-label-Header+Converters].;T@ o;;[I"UAlso by default, each value to be written during generation is written 'as-is'. ;TI"GYou can use a _write_ _converter_ to modify values before writing.;To; ;;;[o;;0;[o;;[I"?See {Write Converters}[#class-CSV-label-Write+Converters].;T@ S; ; i ;I"Specifying \Converters;T@ o;;[I"KYou can specify converters for parsing or generating in the +options+ ;TI"&argument to various \CSV methods:;To; ;;;[o;;0;[o;;[I"<Option +converters+ for converting parsed field values.;To;;0;[o;;[I"DOption +header_converters+ for converting parsed header values.;To;;0;[o;;[I"OOption +write_converters+ for converting values to be written (generated).;T@ o;;[I"5There are three forms for specifying converters:;To; ;;;[o;;0;[o;;[I"AA converter proc: executable code to be used for conversion.;To;;0;[o;;[I"6A converter name: the name of a stored converter.;To;;0;[o;;[I"YA converter list: an array of converter procs, converter names, and converter lists.;T@ S; ; i ;I"Converter Procs;T@ o;;[I"EThis converter proc, +strip_converter+, accepts a value +field+ ;TI"&and returns <tt>field.strip</tt>:;To;;[I"3strip_converter = proc {|field| field.strip } ;T;0o;;[I")In this call to <tt>CSV.parse</tt>, ;TI"@the keyword argument <tt>converters: string_converter</tt> ;TI"specifies that:;To; ;;;[o;;0;[o;;[I"D\Proc +string_converter+ is to be called for each parsed field.;To;;0;[o;;[I"BThe converter's return value is to replace the +field+ value.;To;;[I" Example:;To;;[I"2string = " foo , 0 \n bar , 1 \n baz , 2 \n" ;TI"<array = CSV.parse(string, converters: strip_converter) ;TI";array # => [["foo", "0"], ["bar", "1"], ["baz", "2"]] ;T;0o;;[I"CA converter proc can receive a second argument, +field_info+, ;TI",that contains details about the field. ;TI"<This modified +strip_converter+ displays its arguments:;To;;[I"3strip_converter = proc do |field, field_info| ;TI" p [field, field_info] ;TI" field.strip ;TI" end ;TI"2string = " foo , 0 \n bar , 1 \n baz , 2 \n" ;TI"<array = CSV.parse(string, converters: strip_converter) ;TI";array # => [["foo", "0"], ["bar", "1"], ["baz", "2"]] ;T;0o;;[I"Output:;To;;[I"E[" foo ", #<struct CSV::FieldInfo index=0, line=1, header=nil>] ;TI"C[" 0 ", #<struct CSV::FieldInfo index=1, line=1, header=nil>] ;TI"E[" bar ", #<struct CSV::FieldInfo index=0, line=2, header=nil>] ;TI"C[" 1 ", #<struct CSV::FieldInfo index=1, line=2, header=nil>] ;TI"E[" baz ", #<struct CSV::FieldInfo index=0, line=3, header=nil>] ;TI"C[" 2 ", #<struct CSV::FieldInfo index=1, line=3, header=nil>] ;T;0o;;[I"!Each CSV::Info object shows:;To; ;;;[o;;0;[o;;[I"The 0-based field index.;To;;0;[o;;[I"The 1-based line index.;To;;0;[o;;[I"The field header, if any.;T@ S; ; i ;I"Stored \Converters;T@ o;;[I"EA converter may be given a name and stored in a structure where ;TI"-the parsing methods can find it by name.;T@ o;;[I"NThe storage structure for field converters is the \Hash CSV::Converters. ;TI"-It has several built-in converter procs:;To; ;;;[ o;;0;[o;;[I"T<tt>:integer</tt>: converts each \String-embedded integer into a true \Integer.;To;;0;[o;;[I"N<tt>:float</tt>: converts each \String-embedded float into a true \Float.;To;;0;[o;;[I"K<tt>:date</tt>: converts each \String-embedded date into a true \Date.;To;;0;[o;;[I"X<tt>:date_time</tt>: converts each \String-embedded date-time into a true \DateTime;To;;[I". ;TI";This example creates a converter proc, then stores it:;To;;[I"3strip_converter = proc {|field| field.strip } ;TI"/CSV::Converters[:strip] = strip_converter ;T;0o;;[I"=Then the parsing method call can refer to the converter ;TI""by its name, <tt>:strip</tt>:;To;;[I"2string = " foo , 0 \n bar , 1 \n baz , 2 \n" ;TI"3array = CSV.parse(string, converters: :strip) ;TI";array # => [["foo", "0"], ["bar", "1"], ["baz", "2"]] ;T;0o;;[I"UThe storage structure for header converters is the \Hash CSV::HeaderConverters, ;TI""which works in the same way. ;TI"*It also has built-in converter procs:;To; ;;;[o;;0;[o;;[I"/<tt>:downcase</tt>: Downcases each header.;To;;0;[o;;[I"9<tt>:symbol</tt>: Converts each header to a \Symbol.;T@ o;;[I":There is no such storage structure for write headers.;T@ S; ; i ;I"Converter Lists;T@ o;;[I"JA _converter_ _list_ is an \Array that may include any assortment of:;To; ;;;[o;;0;[o;;[I"Converter procs.;To;;0;[o;;[I" Names of stored converters.;To;;0;[o;;[I"Nested converter lists.;T@ o;;[I"Examples:;To;;[ I"-numeric_converters = [:integer, :float] ;TI"+date_converters = [:date, :date_time] ;TI"+[numeric_converters, strip_converter] ;TI"0[strip_converter, date_converters, :float] ;T;0o;;[I"OLike a converter proc, a converter list may be named and stored in either ;TI"/\CSV::Converters or CSV::HeaderConverters:;To;;[I"KCSV::Converters[:custom] = [strip_converter, date_converters, :float] ;TI";CSV::HeaderConverters[:custom] = [:downcase, :symbol] ;T;0o;;[I",There are two built-in converter lists:;To;;[I"7CSV::Converters[:numeric] # => [:integer, :float] ;TI"7CSV::Converters[:all] # => [:date_time, :numeric] ;T;0S; ; i ;I"Field \Converters;T@ o;;[I"FWith no conversion, all parsed fields in all rows become Strings:;To;;[I"&string = "foo,0\nbar,1\nbaz,2\n" ;TI"ary = CSV.parse(string) ;TI">ary # => # => [["foo", "0"], ["bar", "1"], ["baz", "2"]] ;T;0o;;[ I"WWhen you specify a field converter, each parsed field is passed to the converter; ;TI">its return value becomes the stored value for the field. ;TI"NA converter might, for example, convert an integer embedded in a \String ;TI"into a true \Integer. ;TI"E(In fact, that's what built-in field converter +:integer+ does.);T@ o;;[I"3There are three ways to use field \converters.;T@ o; ;;;[o;;0;[o;;[I"YUsing option {converters}[#class-CSV-label-Option+converters] with a parsing method:;To;;[I"3ary = CSV.parse(string, converters: :integer) ;TI"Bary # => [0, 1, 2] # => [["foo", 0], ["bar", 1], ["baz", 2]] ;T;0o;;0;[o;;[I"\Using option {converters}[#class-CSV-label-Option+converters] with a new \CSV instance:;To;;[ I"1csv = CSV.new(string, converters: :integer) ;TI"## Field converters in effect: ;TI"$csv.converters # => [:integer] ;TI"8csv.read # => [["foo", 0], ["bar", 1], ["baz", 2]] ;T;0o;;0;[o;;[I"GUsing method #convert to add a field converter to a \CSV instance:;To;;[ I"csv = CSV.new(string) ;TI"# Add a converter. ;TI"csv.convert(:integer) ;TI"$csv.converters # => [:integer] ;TI"8csv.read # => [["foo", 0], ["bar", 1], ["baz", 2]] ;T;0o;;[I"DInstalling a field converter does not affect already-read rows:;To;;[I"csv = CSV.new(string) ;TI"!csv.shift # => ["foo", "0"] ;TI"# Add a converter. ;TI"csv.convert(:integer) ;TI"$csv.converters # => [:integer] ;TI",csv.read # => [["bar", 1], ["baz", 2]] ;T;0o;;[I"ZThere are additional built-in \converters, and custom \converters are also supported.;T@ S; ; i ;I"Built-In Field \Converters;T@ o;;[I"@The built-in field converters are in \Hash CSV::Converters:;To; ;;;[o;;0;[o;;[I"(Each key is a field converter name.;To;;0;[o;;[I"Each value is one of:;To; ;;;[o;;0;[o;;[I"A \Proc field converter.;To;;0;[o;;[I"(An \Array of field converter names.;T@ o;;[I" Display:;To;;[I"0CSV::Converters.each_pair do |name, value| ;TI" if value.kind_of?(Proc) ;TI" p [name, value.class] ;TI" else ;TI" p [name, value] ;TI" end ;TI" end ;T;0o;;[I"Output:;To;;[I"[:integer, Proc] ;TI"[:float, Proc] ;TI"$[:numeric, [:integer, :float]] ;TI"[:date, Proc] ;TI"[:date_time, Proc] ;TI"$[:all, [:date_time, :numeric]] ;T;0o;;[I"WEach of these converters transcodes values to UTF-8 before attempting conversion. ;TI"BIf a value cannot be transcoded to UTF-8 the conversion will ;TI"0fail and the value will remain unconverted.;T@ o;;[I"EConverter +:integer+ converts each field that Integer() accepts:;To;;[I"data = '0,1,2,x' ;TI"# Without the converter ;TI" csv = CSV.parse_line(data) ;TI"#csv # => ["0", "1", "2", "x"] ;TI"# With the converter ;TI"6csv = CSV.parse_line(data, converters: :integer) ;TI"csv # => [0, 1, 2, "x"] ;T;0o;;[I"AConverter +:float+ converts each field that Float() accepts:;To;;[I"data = '1.0,3.14159,x' ;TI"# Without the converter ;TI" csv = CSV.parse_line(data) ;TI"&csv # => ["1.0", "3.14159", "x"] ;TI"# With the converter ;TI"4csv = CSV.parse_line(data, converters: :float) ;TI""csv # => [1.0, 3.14159, "x"] ;T;0o;;[I"FConverter +:numeric+ converts with both +:integer+ and +:float+..;T@ o;;[I"DConverter +:date+ converts each field that Date::parse accepts:;To;;[I"data = '2001-02-03,x' ;TI"# Without the converter ;TI" csv = CSV.parse_line(data) ;TI""csv # => ["2001-02-03", "x"] ;TI"# With the converter ;TI"3csv = CSV.parse_line(data, converters: :date) ;TI"Icsv # => [#<Date: 2001-02-03 ((2451944j,0s,0n),+0s,2299161j)>, "x"] ;T;0o;;[I"MConverter +:date_time+ converts each field that DateTime::parse accepts:;To;;[I"*data = '2020-05-07T14:59:00-05:00,x' ;TI"# Without the converter ;TI" csv = CSV.parse_line(data) ;TI"1csv # => ["2020-05-07T14:59:00-05:00", "x"] ;TI"# With the converter ;TI"8csv = CSV.parse_line(data, converters: :date_time) ;TI"dcsv # => [#<DateTime: 2020-05-07T14:59:00-05:00 ((2458977j,71940s,0n),-18000s,2299161j)>, "x"] ;T;0o;;[I"JConverter +:numeric+ converts with both +:date_time+ and +:numeric+..;T@ o;;[I"IAs seen above, method #convert adds \converters to a \CSV instance, ;TI"Kand method #converters returns an \Array of the \converters in effect:;To;;[I"csv = CSV.new('0,1,2') ;TI"csv.converters # => [] ;TI"csv.convert(:integer) ;TI"$csv.converters # => [:integer] ;TI"csv.convert(:date) ;TI"+csv.converters # => [:integer, :date] ;T;0S; ; i ;I"Custom Field \Converters;T@ o;;[I"-You can define a custom field converter:;To;;[ I"3strip_converter = proc {|field| field.strip } ;TI"2string = " foo , 0 \n bar , 1 \n baz , 2 \n" ;TI"<array = CSV.parse(string, converters: strip_converter) ;TI";array # => [["foo", "0"], ["bar", "1"], ["baz", "2"]] ;T;0o;;[I":You can register the converter in \Converters \Hash, ;TI"-which allows you to refer to it by name:;To;;[ I"/CSV::Converters[:strip] = strip_converter ;TI"2string = " foo , 0 \n bar , 1 \n baz , 2 \n" ;TI"3array = CSV.parse(string, converters: :strip) ;TI";array # => [["foo", "0"], ["bar", "1"], ["baz", "2"]] ;T;0S; ; i ;I"Header \Converters;T@ o;;[I"GHeader converters operate only on headers (and not on other rows).;T@ o;;[I"5There are three ways to use header \converters; ;TI"?these examples use built-in header converter +:dowhcase+, ;TI"(which downcases each parsed header.;T@ o; ;;;[o;;0;[o;;[I"@Option +header_converters+ with a singleton parsing method:;To;;[ I"1string = "Name,Count\nFoo,0\n,Bar,1\nBaz,2" ;TI"Jtbl = CSV.parse(string, headers: true, header_converters: :downcase) ;TI"tbl.class # => CSV::Table ;TI"(tbl.headers # => ["name", "count"] ;T;0o;;0;[o;;[I"9Option +header_converters+ with a new \CSV instance:;To;;[ I"9csv = CSV.new(string, header_converters: :downcase) ;TI"$# Header converters in effect: ;TI",csv.header_converters # => [:downcase] ;TI",tbl = CSV.parse(string, headers: true) ;TI"(tbl.headers # => ["Name", "Count"] ;T;0o;;0;[o;;[I"GMethod #header_convert adds a header converter to a \CSV instance:;To;;[I"csv = CSV.new(string) ;TI"# Add a header converter. ;TI"#csv.header_convert(:downcase) ;TI",csv.header_converters # => [:downcase] ;TI",tbl = CSV.parse(string, headers: true) ;TI"(tbl.headers # => ["Name", "Count"] ;T;0S; ; i ;I" Built-In Header \Converters;T@ o;;[I"IThe built-in header \converters are in \Hash CSV::HeaderConverters. ;TI"5The keys there are the names of the \converters:;To;;[I":CSV::HeaderConverters.keys # => [:downcase, :symbol] ;T;0o;;[I"AConverter +:downcase+ converts each header by downcasing it:;To;;[ I"1string = "Name,Count\nFoo,0\n,Bar,1\nBaz,2" ;TI"Jtbl = CSV.parse(string, headers: true, header_converters: :downcase) ;TI"tbl.class # => CSV::Table ;TI"(tbl.headers # => ["name", "count"] ;T;0o;;[I"JConverter +:symbol+ converts each header by making it into a \Symbol:;To;;[I"1string = "Name,Count\nFoo,0\n,Bar,1\nBaz,2" ;TI"Htbl = CSV.parse(string, headers: true, header_converters: :symbol) ;TI"&tbl.headers # => [:name, :count] ;T;0o;;[I" Details:;To; ;;;[ o;;0;[o;;[I",Strips leading and trailing whitespace.;To;;0;[o;;[I"Downcases the header.;To;;0;[o;;[I"/Replaces embedded spaces with underscores.;To;;0;[o;;[I"!Removes non-word characters.;To;;0;[o;;[I"%Makes the string into a \Symbol.;T@ S; ; i ;I"Custom Header \Converters;T@ o;;[I".You can define a custom header converter:;To;;[ I"7upcase_converter = proc {|header| header.upcase } ;TI"2string = "Name,Value\nfoo,0\nbar,1\nbaz,2\n" ;TI"Stable = CSV.parse(string, headers: true, header_converters: upcase_converter) ;TI":table # => #<CSV::Table mode:col_or_row row_count:4> ;TI"*table.headers # => ["NAME", "VALUE"] ;T;0o;;[I"@You can register the converter in \HeaderConverters \Hash, ;TI"-which allows you to refer to it by name:;To;;[ I"7CSV::HeaderConverters[:upcase] = upcase_converter ;TI"Jtable = CSV.parse(string, headers: true, header_converters: :upcase) ;TI":table # => #<CSV::Table mode:col_or_row row_count:4> ;TI"*table.headers # => ["NAME", "VALUE"] ;T;0S; ; i ;I"Write \Converters;T@ o;;[ I"=When you specify a write converter for generating \CSV, ;TI":each field to be written is passed to the converter; ;TI";its return value becomes the new value for the field. ;TI"CA converter might, for example, strip whitespace from a field.;T@ o;;[I"6Using no write converter (all fields unmodified):;To;;[I"+output_string = CSV.generate do |csv| ;TI" csv << [' foo ', 0] ;TI" csv << [' bar ', 1] ;TI" csv << [' baz ', 2] ;TI" end ;TI"6output_string # => " foo ,0\n bar ,1\n baz ,2\n" ;T;0o;;[I"FUsing option +write_converters+ with two custom write converters:;To;;[I"Wstrip_converter = proc {|field| field.respond_to?(:strip) ? field.strip : field } ;TI"Zupcase_converter = proc {|field| field.respond_to?(:upcase) ? field.upcase : field } ;TI"<write_converters = [strip_converter, upcase_converter] ;TI"Ooutput_string = CSV.generate(write_converters: write_converters) do |csv| ;TI" csv << [' foo ', 0] ;TI" csv << [' bar ', 1] ;TI" csv << [' baz ', 2] ;TI" end ;TI"0output_string # => "FOO,0\nBAR,1\nBAZ,2\n" ;T;0S; ; i;I"6Character Encodings (M17n or Multilingualization);T@ o;;[I"TThis new CSV parser is m17n savvy. The parser works in the Encoding of the IO ;TI"Sor String object being read from or written to. Your data is never transcoded ;TI"S(unless you ask Ruby to transcode it for you) and will literally be parsed in ;TI"Rthe Encoding it is in. Thus CSV will return Arrays or Rows of Strings in the ;TI"REncoding of your data. This is accomplished by transcoding the parser itself ;TI"into your Encoding.;T@ o;;[I"SSome transcoding must take place, of course, to accomplish this multiencoding ;TI"Esupport. For example, <tt>:col_sep</tt>, <tt>:row_sep</tt>, and ;TI"Q<tt>:quote_char</tt> must be transcoded to match your data. Hopefully this ;TI"Qmakes the entire process feel transparent, since CSV's defaults should just ;TI"Qmagically work for your data. However, you can set these values manually in ;TI"2the target Encoding to avoid the translation.;T@ o;;[I"LIt's also important to note that while all of CSV's core parser is now ;TI"IEncoding agnostic, some features are not. For example, the built-in ;TI"Oconverters will try to transcode data to UTF-8 before making conversions. ;TI"RAgain, you can provide custom converters that are aware of your Encodings to ;TI"Iavoid this translation. It's just too hard for me to support native ;TI",conversions in all of Ruby's Encodings.;T@ o;;[ I"SAnyway, the practical side of this is simple: make sure IO and String objects ;TI"Spassed into CSV have the proper Encoding set and everything should just work. ;TI"QCSV methods that allow you to open IO objects (CSV::foreach(), CSV::open(), ;TI"MCSV::read(), and CSV::readlines()) do allow you to specify the Encoding.;T@ o;;[ I"ROne minor exception comes when generating CSV into a String with an Encoding ;TI"Nthat is not ASCII compatible. There's no existing data for CSV to use to ;TI"Tprepare itself and thus you will probably need to manually specify the desired ;TI"REncoding for most of those cases. It will try to guess using the fields in a ;TI"Mrow of output though, when using CSV::generate_line() or Array#to_csv().;T@ o;;[I"RI try to point out any other Encoding issues in the documentation of methods ;TI"as they come up.;T@ o;;[ I"SThis has been tested to the best of my ability with all non-"dummy" Encodings ;TI"LRuby ships with. However, it is brave new code and may have some bugs. ;TI"SPlease feel free to {report}[mailto:james@grayproductions.net] any issues you ;TI"find with it.;T: @fileI"lib/csv.rb;T:0@omit_headings_from_table_of_contents_below0o;;[ ;I"lib/csv/delete_suffix.rb;T;0o;;[ ;I" lib/csv/fields_converter.rb;T;0o;;[ ;I"lib/csv/match_p.rb;T;0o;;[ ;I"lib/csv/parser.rb;T;0o;;[ ;I"lib/csv/row.rb;T;0o;;[ ;I"lib/csv/table.rb;T;0o;;[ ;I"lib/csv/version.rb;T;0o;;[ ;I"lib/csv/writer.rb;T;0;0;0[[ I" encoding;TI"R;T:publicFI"lib/csv.rb;T[ U:RDoc::Constant[i I"FieldInfo;TI"CSV::FieldInfo;T;0o;;[o;;[ I"NA FieldInfo Struct contains details about a field's position in the data ;TI"Rsource it was read from. CSV will pass this Struct to some blocks that make ;TI"Jdecisions based on field structure. See CSV.convert_fields() for an ;TI" example.;T@ o; ;: NOTE;[o;;[I"<b><tt>index</tt></b>;T;[o;;[I"2The zero-based index of the field in its row.;To;;[I"<b><tt>line</tt></b>;T;[o;;[I"2The line of the data source this row is from.;To;;[I"<b><tt>header</tt></b>;T;[o;;[I"/The header for the column, when available.;T;@� ;0@� @cRDoc::NormalClass0U;[i I"DateMatcher;TI"CSV::DateMatcher;T;0o;;[o;;[I"@A Regexp used to find and convert some common Date formats.;T;@� ;0@� @@� 0U;[i I"DateTimeMatcher;TI"CSV::DateTimeMatcher;T;0o;;[o;;[I"DA Regexp used to find and convert some common DateTime formats.;T;@� ;0@� @@� 0U;[i I"ConverterEncoding;TI"CSV::ConverterEncoding;T;0o;;[o;;[I")The encoding used by all converters.;T;@� ;0@� @@� 0U;[i I"Converters;TI"CSV::Converters;T;0o;;[o;;[I"PA \Hash containing the names and \Procs for the built-in field converters. ;TI"QSee {Built-In Field Converters}[#class-CSV-label-Built-In+Field+Converters].;T@ o;;[I"IThis \Hash is intentionally left unfrozen, and may be extended with ;TI"custom field converters. ;TI"MSee {Custom Field Converters}[#class-CSV-label-Custom+Field+Converters].;T;@� ;0@� @@� 0U;[i I"HeaderConverters;TI"CSV::HeaderConverters;T;0o;;[o;;[I"QA \Hash containing the names and \Procs for the built-in header converters. ;TI"SSee {Built-In Header Converters}[#class-CSV-label-Built-In+Header+Converters].;T@ o;;[I"IThis \Hash is intentionally left unfrozen, and may be extended with ;TI"custom field converters. ;TI"OSee {Custom Header Converters}[#class-CSV-label-Custom+Header+Converters].;T;@� ;0@� @@� 0U;[i I"DEFAULT_OPTIONS;TI"CSV::DEFAULT_OPTIONS;T;0o;;[o;;[I"'Default values for method options.;T;@� ;0@� @@� 0U;[i I"VERSION;TI"CSV::VERSION;T;0o;;[o;;[I"*The version of the installed library.;T;@� ;0@� @@� 0[[I"Enumerable;To;;[ ;@� ;0@� [[I" class;T[[;[[I"filter;T@� [I"foreach;T@� [I" generate;T@� [I"generate_line;T@� [I" instance;T@� [I"new;T@� [I" open;T@� [I" parse;T@� [I"parse_line;T@� [I" read;T@� [I"readlines;T@� [I" table;T@� [:protected[ [:private[ [I" instance;T[[;[,[I"<<;T@� [I"add_row;T@� [I" binmode?;T@� [I"col_sep;T@� [I"convert;T@� [I"converters;T@� [I" each;T@� [I"eof;T@� [I" eof?;T@� [I"field_size_limit;T@� [I" flock;T@� [I"force_quotes?;T@� [I" gets;T@� [I"header_convert;T@� [I"header_converters;T@� [I"header_row?;T@� [I"headers;T@� [I"inspect;T@� [I" ioctl;T@� [I"liberal_parsing?;T@� [I" line;T@� [I"lineno;T@� [I" path;T@� [I" puts;T@� [I"quote_char;T@� [I" read;T@� [I" readline;T@� [I"readlines;T@� [I"return_headers?;T@� [I"rewind;T@� [I"row_sep;T@� [I" shift;T@� [I"skip_blanks?;T@� [I"skip_lines;T@� [I" stat;T@� [I" to_i;T@� [I" to_io;T@� [I"unconverted_fields?;T@� [I"write_headers?;T@� [;[ [;[[I"build_fields_converter;T@� [I""build_header_fields_converter;T@� [I""build_parser_fields_converter;T@� [I""build_writer_fields_converter;T@� [I"convert_fields;T@� [I"determine_encoding;T@� [I"header_fields_converter;T@� [I"normalize_converters;T@� [I"parser;T@� [I"parser_enumerator;T@� [I"parser_fields_converter;T@� [I"parser_options;T@� [I"raw_encoding;T@� [I"writer;T@� [I"writer_fields_converter;T@� [I"writer_options;T@� [[I"Forwardable;To;;[o;;[I"#IO and StringIO Delegation ###;T;@� ;0@� [U:RDoc::Context::Section[i 0o;;[ ;0;0[@� @� @� @� @� @� @� @� @� @� cRDoc::TopLevel
Simpan