class CSV::Writer
Note: Don’t use this class directly. This is an internal class.
Attributes
headers[R]
lineno[R]
A CSV::Writer
receives an output, prepares the header, format and output. It allows us to write new rows in the object and rewind it.
Public Class Methods
new(output, options)
click to toggle source
# File csv/writer.rb, line 19 def initialize(output, options) @output = output @options = options @lineno = 0 @fields_converter = nil prepare if @options[:write_headers] and @headers self << @headers end @fields_converter = @options[:fields_converter] end
Public Instance Methods
<<(row)
click to toggle source
Adds a new row
# File csv/writer.rb, line 34 def <<(row) case row when Row row = row.fields when Hash row = @headers.collect {|header| row[header]} end @headers ||= row if @use_headers @lineno += 1 row = @fields_converter.convert(row, nil, lineno) if @fields_converter i = -1 converted_row = row.collect do |field| i += 1 quote(field, i) end line = converted_row.join(@column_separator) + @row_separator if @output_encoding line = line.encode(@output_encoding) end @output << line self end
rewind()
click to toggle source
Winds back to the beginning
# File csv/writer.rb, line 64 def rewind @lineno = 0 @headers = nil if @options[:headers].nil? end
Private Instance Methods
prepare()
click to toggle source
# File csv/writer.rb, line 70 def prepare @encoding = @options[:encoding] prepare_header prepare_format prepare_output end
prepare_force_quotes_fields(force_quotes)
click to toggle source
# File csv/writer.rb, line 106 def prepare_force_quotes_fields(force_quotes) @force_quotes_fields = {} force_quotes.each do |name_or_index| case name_or_index when Integer index = name_or_index @force_quotes_fields[index] = true when String, Symbol name = name_or_index.to_s if @headers.nil? message = ":headers is required when you use field name " + "in :force_quotes: " + "#{name_or_index.inspect}: #{force_quotes.inspect}" raise ArgumentError, message end index = @headers.index(name) next if index.nil? @force_quotes_fields[index] = true else message = ":force_quotes element must be " + "field index or field name: " + "#{name_or_index.inspect}: #{force_quotes.inspect}" raise ArgumentError, message end end end
prepare_format()
click to toggle source
# File csv/writer.rb, line 133 def prepare_format @column_separator = @options[:column_separator].to_s.encode(@encoding) row_separator = @options[:row_separator] if row_separator == :auto @row_separator = InputRecordSeparator.value.encode(@encoding) else @row_separator = row_separator.to_s.encode(@encoding) end @quote_character = @options[:quote_character] force_quotes = @options[:force_quotes] if force_quotes.is_a?(Array) prepare_force_quotes_fields(force_quotes) @force_quotes = false elsif force_quotes @force_quotes_fields = nil @force_quotes = true else @force_quotes_fields = nil @force_quotes = false end unless @force_quotes @quotable_pattern = Regexp.new("[\r\n".encode(@encoding) + Regexp.escape(@column_separator) + Regexp.escape(@quote_character.encode(@encoding)) + "]".encode(@encoding)) end @quote_empty = @options.fetch(:quote_empty, true) end
prepare_header()
click to toggle source
# File csv/writer.rb, line 78 def prepare_header headers = @options[:headers] case headers when Array @headers = headers @use_headers = true when String @headers = CSV.parse_line(headers, col_sep: @options[:column_separator], row_sep: @options[:row_separator], quote_char: @options[:quote_character]) @use_headers = true when true @headers = nil @use_headers = true else @headers = nil @use_headers = false end return unless @headers converter = @options[:header_fields_converter] @headers = converter.convert(@headers, nil, 0) @headers.each do |header| header.freeze if header.is_a?(String) end end
prepare_output()
click to toggle source
# File csv/writer.rb, line 163 def prepare_output @output_encoding = nil return unless @output.is_a?(StringIO) output_encoding = @output.internal_encoding || @output.external_encoding if @encoding != output_encoding if @options[:force_encoding] @output_encoding = output_encoding else compatible_encoding = Encoding.compatible?(@encoding, output_encoding) if compatible_encoding @output.set_encoding(compatible_encoding) @output.seek(0, IO::SEEK_END) end end end end
quote(field, i)
click to toggle source
# File csv/writer.rb, line 190 def quote(field, i) if @force_quotes quote_field(field) elsif @force_quotes_fields and @force_quotes_fields[i] quote_field(field) else if field.nil? # represent +nil+ fields as empty unquoted fields "" else field = String(field) # Stringify fields # represent empty fields as empty quoted fields if (@quote_empty and field.empty?) or (field.valid_encoding? and @quotable_pattern.match?(field)) quote_field(field) else field # unquoted field end end end end
quote_field(field)
click to toggle source
# File csv/writer.rb, line 181 def quote_field(field) field = String(field) encoded_quote_character = @quote_character.encode(field.encoding) encoded_quote_character + field.gsub(encoded_quote_character, encoded_quote_character * 2) + encoded_quote_character end