# typed: false # DO NOT EDIT MANUALLY # This is an autogenerated file for types exported from the `csv` gem. # Please instead update this file by running `bin/tapioca gem csv`. # source://csv//lib/csv/core_ext/array.rb#1 class Array include ::Enumerable # Equivalent to CSV::generate_line(self, options) # # ["CSV", "data"].to_csv # #=> "CSV,data\n" # # source://csv//lib/csv/core_ext/array.rb#6 def to_csv(**options); end end # == \CSV # # === \CSV Data # # \CSV (comma-separated values) data is a text representation of a table: # - A _row_ _separator_ delimits table rows. # A common row separator is the newline character "\n". # - A _column_ _separator_ delimits fields in a row. # A common column separator is the comma character ",". # # This \CSV \String, with row separator "\n" # and column separator ",", # has three rows and two columns: # "foo,0\nbar,1\nbaz,2\n" # # Despite the name \CSV, a \CSV representation can use different separators. # # For more about tables, see the Wikipedia article # "{Table (information)}[https://en.wikipedia.org/wiki/Table_(information)]", # especially its section # "{Simple table}[https://en.wikipedia.org/wiki/Table_(information)#Simple_table]" # # == \Class \CSV # # Class \CSV provides methods for: # - Parsing \CSV data from a \String object, a \File (via its file path), or an \IO object. # - Generating \CSV data to a \String object. # # To make \CSV available: # require 'csv' # # All examples here assume that this has been done. # # == Keeping It Simple # # A \CSV object has dozens of instance methods that offer fine-grained control # of parsing and generating \CSV data. # For many needs, though, simpler approaches will do. # # This section summarizes the singleton methods in \CSV # that allow you to parse and generate without explicitly # creating \CSV objects. # For details, follow the links. # # === Simple Parsing # # Parsing methods commonly return either of: # - An \Array of Arrays of Strings: # - The outer \Array is the entire "table". # - Each inner \Array is a row. # - Each \String is a field. # - A CSV::Table object. For details, see # {\CSV with Headers}[#class-CSV-label-CSV+with+Headers]. # # ==== Parsing a \String # # The input to be parsed can be a string: # string = "foo,0\nbar,1\nbaz,2\n" # # \Method CSV.parse returns the entire \CSV data: # CSV.parse(string) # => [["foo", "0"], ["bar", "1"], ["baz", "2"]] # # \Method CSV.parse_line returns only the first row: # CSV.parse_line(string) # => ["foo", "0"] # # \CSV extends class \String with instance method String#parse_csv, # which also returns only the first row: # string.parse_csv # => ["foo", "0"] # # ==== Parsing Via a \File Path # # The input to be parsed can be in a file: # string = "foo,0\nbar,1\nbaz,2\n" # path = 't.csv' # File.write(path, string) # # \Method CSV.read returns the entire \CSV data: # CSV.read(path) # => [["foo", "0"], ["bar", "1"], ["baz", "2"]] # # \Method CSV.foreach iterates, passing each row to the given block: # CSV.foreach(path) do |row| # p row # end # Output: # ["foo", "0"] # ["bar", "1"] # ["baz", "2"] # # \Method CSV.table returns the entire \CSV data as a CSV::Table object: # CSV.table(path) # => # # # ==== Parsing from an Open \IO Stream # # The input to be parsed can be in an open \IO stream: # # \Method CSV.read returns the entire \CSV data: # File.open(path) do |file| # CSV.read(file) # end # => [["foo", "0"], ["bar", "1"], ["baz", "2"]] # # As does method CSV.parse: # File.open(path) do |file| # CSV.parse(file) # end # => [["foo", "0"], ["bar", "1"], ["baz", "2"]] # # \Method CSV.parse_line returns only the first row: # File.open(path) do |file| # CSV.parse_line(file) # end # => ["foo", "0"] # # \Method CSV.foreach iterates, passing each row to the given block: # File.open(path) do |file| # CSV.foreach(file) do |row| # p row # end # end # Output: # ["foo", "0"] # ["bar", "1"] # ["baz", "2"] # # \Method CSV.table returns the entire \CSV data as a CSV::Table object: # File.open(path) do |file| # CSV.table(file) # end # => # # # === Simple Generating # # \Method CSV.generate returns a \String; # this example uses method CSV#<< to append the rows # that are to be generated: # output_string = CSV.generate do |csv| # csv << ['foo', 0] # csv << ['bar', 1] # csv << ['baz', 2] # end # output_string # => "foo,0\nbar,1\nbaz,2\n" # # \Method CSV.generate_line returns a \String containing the single row # constructed from an \Array: # CSV.generate_line(['foo', '0']) # => "foo,0\n" # # \CSV extends class \Array with instance method Array#to_csv, # which forms an \Array into a \String: # ['foo', '0'].to_csv # => "foo,0\n" # # === "Filtering" \CSV # # \Method CSV.filter provides a Unix-style filter for \CSV data. # The input data is processed to form the output data: # in_string = "foo,0\nbar,1\nbaz,2\n" # out_string = '' # CSV.filter(in_string, out_string) do |row| # row[0] = row[0].upcase # row[1] *= 4 # end # out_string # => "FOO,0000\nBAR,1111\nBAZ,2222\n" # # == \CSV Objects # # There are three ways to create a \CSV object: # - \Method CSV.new returns a new \CSV object. # - \Method CSV.instance returns a new or cached \CSV object. # - \Method \CSV() also returns a new or cached \CSV object. # # === Instance Methods # # \CSV has three groups of instance methods: # - Its own internally defined instance methods. # - Methods included by module Enumerable. # - Methods delegated to class IO. See below. # # ==== Delegated Methods # # For convenience, a CSV object will delegate to many methods in class IO. # (A few have wrapper "guard code" in \CSV.) You may call: # * IO#binmode # * #binmode? # * IO#close # * IO#close_read # * IO#close_write # * IO#closed? # * #eof # * #eof? # * IO#external_encoding # * IO#fcntl # * IO#fileno # * #flock # * IO#flush # * IO#fsync # * IO#internal_encoding # * #ioctl # * IO#isatty # * #path # * IO#pid # * IO#pos # * IO#pos= # * IO#reopen # * #rewind # * IO#seek # * #stat # * IO#string # * IO#sync # * IO#sync= # * IO#tell # * #to_i # * #to_io # * IO#truncate # * IO#tty? # # === Options # # The default values for options are: # DEFAULT_OPTIONS = { # # For both parsing and generating. # col_sep: ",", # row_sep: :auto, # quote_char: '"', # # For parsing. # field_size_limit: nil, # converters: nil, # unconverted_fields: nil, # headers: false, # return_headers: false, # header_converters: nil, # skip_blanks: false, # skip_lines: nil, # liberal_parsing: false, # nil_value: nil, # empty_value: "", # strip: false, # # For generating. # write_headers: nil, # quote_empty: true, # force_quotes: false, # write_converters: nil, # write_nil_value: nil, # write_empty_value: "", # } # # ==== Options for Parsing # # Options for parsing, described in detail below, include: # - +row_sep+: Specifies the row separator; used to delimit rows. # - +col_sep+: Specifies the column separator; used to delimit fields. # - +quote_char+: Specifies the quote character; used to quote fields. # - +field_size_limit+: Specifies the maximum field size + 1 allowed. # Deprecated since 3.2.3. Use +max_field_size+ instead. # - +max_field_size+: Specifies the maximum field size allowed. # - +converters+: Specifies the field converters to be used. # - +unconverted_fields+: Specifies whether unconverted fields are to be available. # - +headers+: Specifies whether data contains headers, # or specifies the headers themselves. # - +return_headers+: Specifies whether headers are to be returned. # - +header_converters+: Specifies the header converters to be used. # - +skip_blanks+: Specifies whether blanks lines are to be ignored. # - +skip_lines+: Specifies how comments lines are to be recognized. # - +strip+: Specifies whether leading and trailing whitespace are to be # stripped from fields. This must be compatible with +col_sep+; if it is not, # then an +ArgumentError+ exception will be raised. # - +liberal_parsing+: Specifies whether \CSV should attempt to parse # non-compliant data. # - +nil_value+: Specifies the object that is to be substituted for each null (no-text) field. # - +empty_value+: Specifies the object that is to be substituted for each empty field. # # :include: ../doc/csv/options/common/row_sep.rdoc # # :include: ../doc/csv/options/common/col_sep.rdoc # # :include: ../doc/csv/options/common/quote_char.rdoc # # :include: ../doc/csv/options/parsing/field_size_limit.rdoc # # :include: ../doc/csv/options/parsing/converters.rdoc # # :include: ../doc/csv/options/parsing/unconverted_fields.rdoc # # :include: ../doc/csv/options/parsing/headers.rdoc # # :include: ../doc/csv/options/parsing/return_headers.rdoc # # :include: ../doc/csv/options/parsing/header_converters.rdoc # # :include: ../doc/csv/options/parsing/skip_blanks.rdoc # # :include: ../doc/csv/options/parsing/skip_lines.rdoc # # :include: ../doc/csv/options/parsing/strip.rdoc # # :include: ../doc/csv/options/parsing/liberal_parsing.rdoc # # :include: ../doc/csv/options/parsing/nil_value.rdoc # # :include: ../doc/csv/options/parsing/empty_value.rdoc # # ==== Options for Generating # # Options for generating, described in detail below, include: # - +row_sep+: Specifies the row separator; used to delimit rows. # - +col_sep+: Specifies the column separator; used to delimit fields. # - +quote_char+: Specifies the quote character; used to quote fields. # - +write_headers+: Specifies whether headers are to be written. # - +force_quotes+: Specifies whether each output field is to be quoted. # - +quote_empty+: Specifies whether each empty output field is to be quoted. # - +write_converters+: Specifies the field converters to be used in writing. # - +write_nil_value+: Specifies the object that is to be substituted for each +nil+-valued field. # - +write_empty_value+: Specifies the object that is to be substituted for each empty field. # # :include: ../doc/csv/options/common/row_sep.rdoc # # :include: ../doc/csv/options/common/col_sep.rdoc # # :include: ../doc/csv/options/common/quote_char.rdoc # # :include: ../doc/csv/options/generating/write_headers.rdoc # # :include: ../doc/csv/options/generating/force_quotes.rdoc # # :include: ../doc/csv/options/generating/quote_empty.rdoc # # :include: ../doc/csv/options/generating/write_converters.rdoc # # :include: ../doc/csv/options/generating/write_nil_value.rdoc # # :include: ../doc/csv/options/generating/write_empty_value.rdoc # # === \CSV with Headers # # CSV allows to specify column names of CSV file, whether they are in data, or # provided separately. If headers are specified, reading methods return an instance # of CSV::Table, consisting of CSV::Row. # # # Headers are part of data # data = CSV.parse(<<~ROWS, headers: true) # Name,Department,Salary # Bob,Engineering,1000 # Jane,Sales,2000 # John,Management,5000 # ROWS # # data.class #=> CSV::Table # data.first #=> # # data.first.to_h #=> {"Name"=>"Bob", "Department"=>"Engineering", "Salary"=>"1000"} # # # Headers provided by developer # data = CSV.parse('Bob,Engineering,1000', headers: %i[name department salary]) # data.first #=> # # # === \Converters # # By default, each value (field or header) parsed by \CSV is formed into a \String. # You can use a _field_ _converter_ or _header_ _converter_ # to intercept and modify the parsed values: # - See {Field Converters}[#class-CSV-label-Field+Converters]. # - See {Header Converters}[#class-CSV-label-Header+Converters]. # # Also by default, each value to be written during generation is written 'as-is'. # You can use a _write_ _converter_ to modify values before writing. # - See {Write Converters}[#class-CSV-label-Write+Converters]. # # ==== Specifying \Converters # # You can specify converters for parsing or generating in the +options+ # argument to various \CSV methods: # - Option +converters+ for converting parsed field values. # - Option +header_converters+ for converting parsed header values. # - Option +write_converters+ for converting values to be written (generated). # # There are three forms for specifying converters: # - A converter proc: executable code to be used for conversion. # - A converter name: the name of a stored converter. # - A converter list: an array of converter procs, converter names, and converter lists. # # ===== Converter Procs # # This converter proc, +strip_converter+, accepts a value +field+ # and returns field.strip: # strip_converter = proc {|field| field.strip } # In this call to CSV.parse, # the keyword argument converters: string_converter # specifies that: # - \Proc +string_converter+ is to be called for each parsed field. # - The converter's return value is to replace the +field+ value. # Example: # string = " foo , 0 \n bar , 1 \n baz , 2 \n" # array = CSV.parse(string, converters: strip_converter) # array # => [["foo", "0"], ["bar", "1"], ["baz", "2"]] # # A converter proc can receive a second argument, +field_info+, # that contains details about the field. # This modified +strip_converter+ displays its arguments: # strip_converter = proc do |field, field_info| # p [field, field_info] # field.strip # end # string = " foo , 0 \n bar , 1 \n baz , 2 \n" # array = CSV.parse(string, converters: strip_converter) # array # => [["foo", "0"], ["bar", "1"], ["baz", "2"]] # Output: # [" foo ", #] # [" 0 ", #] # [" bar ", #] # [" 1 ", #] # [" baz ", #] # [" 2 ", #] # Each CSV::FieldInfo object shows: # - The 0-based field index. # - The 1-based line index. # - The field header, if any. # # ===== Stored \Converters # # A converter may be given a name and stored in a structure where # the parsing methods can find it by name. # # The storage structure for field converters is the \Hash CSV::Converters. # It has several built-in converter procs: # - :integer: converts each \String-embedded integer into a true \Integer. # - :float: converts each \String-embedded float into a true \Float. # - :date: converts each \String-embedded date into a true \Date. # - :date_time: converts each \String-embedded date-time into a true \DateTime # - :time: converts each \String-embedded time into a true \Time # . # This example creates a converter proc, then stores it: # strip_converter = proc {|field| field.strip } # CSV::Converters[:strip] = strip_converter # Then the parsing method call can refer to the converter # by its name, :strip: # string = " foo , 0 \n bar , 1 \n baz , 2 \n" # array = CSV.parse(string, converters: :strip) # array # => [["foo", "0"], ["bar", "1"], ["baz", "2"]] # # The storage structure for header converters is the \Hash CSV::HeaderConverters, # which works in the same way. # It also has built-in converter procs: # - :downcase: Downcases each header. # - :symbol: Converts each header to a \Symbol. # # There is no such storage structure for write headers. # # In order for the parsing methods to access stored converters in non-main-Ractors, the # storage structure must be made shareable first. # Therefore, Ractor.make_shareable(CSV::Converters) and # Ractor.make_shareable(CSV::HeaderConverters) must be called before the creation # of Ractors that use the converters stored in these structures. (Since making the storage # structures shareable involves freezing them, any custom converters that are to be used # must be added first.) # # ===== Converter Lists # # A _converter_ _list_ is an \Array that may include any assortment of: # - Converter procs. # - Names of stored converters. # - Nested converter lists. # # Examples: # numeric_converters = [:integer, :float] # date_converters = [:date, :date_time] # [numeric_converters, strip_converter] # [strip_converter, date_converters, :float] # # Like a converter proc, a converter list may be named and stored in either # \CSV::Converters or CSV::HeaderConverters: # CSV::Converters[:custom] = [strip_converter, date_converters, :float] # CSV::HeaderConverters[:custom] = [:downcase, :symbol] # # There are two built-in converter lists: # CSV::Converters[:numeric] # => [:integer, :float] # CSV::Converters[:all] # => [:date_time, :numeric] # # ==== Field \Converters # # With no conversion, all parsed fields in all rows become Strings: # string = "foo,0\nbar,1\nbaz,2\n" # ary = CSV.parse(string) # ary # => # => [["foo", "0"], ["bar", "1"], ["baz", "2"]] # # When you specify a field converter, each parsed field is passed to the converter; # its return value becomes the stored value for the field. # A converter might, for example, convert an integer embedded in a \String # into a true \Integer. # (In fact, that's what built-in field converter +:integer+ does.) # # There are three ways to use field \converters. # # - Using option {converters}[#class-CSV-label-Option+converters] with a parsing method: # ary = CSV.parse(string, converters: :integer) # ary # => [0, 1, 2] # => [["foo", 0], ["bar", 1], ["baz", 2]] # - Using option {converters}[#class-CSV-label-Option+converters] with a new \CSV instance: # csv = CSV.new(string, converters: :integer) # # Field converters in effect: # csv.converters # => [:integer] # csv.read # => [["foo", 0], ["bar", 1], ["baz", 2]] # - Using method #convert to add a field converter to a \CSV instance: # csv = CSV.new(string) # # Add a converter. # csv.convert(:integer) # csv.converters # => [:integer] # csv.read # => [["foo", 0], ["bar", 1], ["baz", 2]] # # Installing a field converter does not affect already-read rows: # csv = CSV.new(string) # csv.shift # => ["foo", "0"] # # Add a converter. # csv.convert(:integer) # csv.converters # => [:integer] # csv.read # => [["bar", 1], ["baz", 2]] # # There are additional built-in \converters, and custom \converters are also supported. # # ===== Built-In Field \Converters # # The built-in field converters are in \Hash CSV::Converters: # - Each key is a field converter name. # - Each value is one of: # - A \Proc field converter. # - An \Array of field converter names. # # Display: # CSV::Converters.each_pair do |name, value| # if value.kind_of?(Proc) # p [name, value.class] # else # p [name, value] # end # end # Output: # [:integer, Proc] # [:float, Proc] # [:numeric, [:integer, :float]] # [:date, Proc] # [:date_time, Proc] # [:time, Proc] # [:all, [:date_time, :numeric]] # # Each of these converters transcodes values to UTF-8 before attempting conversion. # If a value cannot be transcoded to UTF-8 the conversion will # fail and the value will remain unconverted. # # Converter +:integer+ converts each field that Integer() accepts: # data = '0,1,2,x' # # Without the converter # csv = CSV.parse_line(data) # csv # => ["0", "1", "2", "x"] # # With the converter # csv = CSV.parse_line(data, converters: :integer) # csv # => [0, 1, 2, "x"] # # Converter +:float+ converts each field that Float() accepts: # data = '1.0,3.14159,x' # # Without the converter # csv = CSV.parse_line(data) # csv # => ["1.0", "3.14159", "x"] # # With the converter # csv = CSV.parse_line(data, converters: :float) # csv # => [1.0, 3.14159, "x"] # # Converter +:numeric+ converts with both +:integer+ and +:float+.. # # Converter +:date+ converts each field that Date::parse accepts: # data = '2001-02-03,x' # # Without the converter # csv = CSV.parse_line(data) # csv # => ["2001-02-03", "x"] # # With the converter # csv = CSV.parse_line(data, converters: :date) # csv # => [#, "x"] # # Converter +:date_time+ converts each field that DateTime::parse accepts: # data = '2020-05-07T14:59:00-05:00,x' # # Without the converter # csv = CSV.parse_line(data) # csv # => ["2020-05-07T14:59:00-05:00", "x"] # # With the converter # csv = CSV.parse_line(data, converters: :date_time) # csv # => [#, "x"] # # Converter +time+ converts each field that Time::parse accepts: # data = '2020-05-07T14:59:00-05:00,x' # # Without the converter # csv = CSV.parse_line(data) # csv # => ["2020-05-07T14:59:00-05:00", "x"] # # With the converter # csv = CSV.parse_line(data, converters: :time) # csv # => [2020-05-07 14:59:00 -0500, "x"] # # Converter +:numeric+ converts with both +:date_time+ and +:numeric+.. # # As seen above, method #convert adds \converters to a \CSV instance, # and method #converters returns an \Array of the \converters in effect: # csv = CSV.new('0,1,2') # csv.converters # => [] # csv.convert(:integer) # csv.converters # => [:integer] # csv.convert(:date) # csv.converters # => [:integer, :date] # # ===== Custom Field \Converters # # You can define a custom field converter: # strip_converter = proc {|field| field.strip } # string = " foo , 0 \n bar , 1 \n baz , 2 \n" # array = CSV.parse(string, converters: strip_converter) # array # => [["foo", "0"], ["bar", "1"], ["baz", "2"]] # You can register the converter in \Converters \Hash, # which allows you to refer to it by name: # CSV::Converters[:strip] = strip_converter # string = " foo , 0 \n bar , 1 \n baz , 2 \n" # array = CSV.parse(string, converters: :strip) # array # => [["foo", "0"], ["bar", "1"], ["baz", "2"]] # # ==== Header \Converters # # Header converters operate only on headers (and not on other rows). # # There are three ways to use header \converters; # these examples use built-in header converter +:downcase+, # which downcases each parsed header. # # - Option +header_converters+ with a singleton parsing method: # string = "Name,Count\nFoo,0\n,Bar,1\nBaz,2" # tbl = CSV.parse(string, headers: true, header_converters: :downcase) # tbl.class # => CSV::Table # tbl.headers # => ["name", "count"] # # - Option +header_converters+ with a new \CSV instance: # csv = CSV.new(string, header_converters: :downcase) # # Header converters in effect: # csv.header_converters # => [:downcase] # tbl = CSV.parse(string, headers: true) # tbl.headers # => ["Name", "Count"] # # - Method #header_convert adds a header converter to a \CSV instance: # csv = CSV.new(string) # # Add a header converter. # csv.header_convert(:downcase) # csv.header_converters # => [:downcase] # tbl = CSV.parse(string, headers: true) # tbl.headers # => ["Name", "Count"] # # ===== Built-In Header \Converters # # The built-in header \converters are in \Hash CSV::HeaderConverters. # The keys there are the names of the \converters: # CSV::HeaderConverters.keys # => [:downcase, :symbol] # # Converter +:downcase+ converts each header by downcasing it: # string = "Name,Count\nFoo,0\n,Bar,1\nBaz,2" # tbl = CSV.parse(string, headers: true, header_converters: :downcase) # tbl.class # => CSV::Table # tbl.headers # => ["name", "count"] # # Converter +:symbol+ converts each header by making it into a \Symbol: # string = "Name,Count\nFoo,0\n,Bar,1\nBaz,2" # tbl = CSV.parse(string, headers: true, header_converters: :symbol) # tbl.headers # => [:name, :count] # Details: # - Strips leading and trailing whitespace. # - Downcases the header. # - Replaces embedded spaces with underscores. # - Removes non-word characters. # - Makes the string into a \Symbol. # # ===== Custom Header \Converters # # You can define a custom header converter: # upcase_converter = proc {|header| header.upcase } # string = "Name,Value\nfoo,0\nbar,1\nbaz,2\n" # table = CSV.parse(string, headers: true, header_converters: upcase_converter) # table # => # # table.headers # => ["NAME", "VALUE"] # You can register the converter in \HeaderConverters \Hash, # which allows you to refer to it by name: # CSV::HeaderConverters[:upcase] = upcase_converter # table = CSV.parse(string, headers: true, header_converters: :upcase) # table # => # # table.headers # => ["NAME", "VALUE"] # # ===== Write \Converters # # When you specify a write converter for generating \CSV, # each field to be written is passed to the converter; # its return value becomes the new value for the field. # A converter might, for example, strip whitespace from a field. # # Using no write converter (all fields unmodified): # output_string = CSV.generate do |csv| # csv << [' foo ', 0] # csv << [' bar ', 1] # csv << [' baz ', 2] # end # output_string # => " foo ,0\n bar ,1\n baz ,2\n" # Using option +write_converters+ with two custom write converters: # strip_converter = proc {|field| field.respond_to?(:strip) ? field.strip : field } # upcase_converter = proc {|field| field.respond_to?(:upcase) ? field.upcase : field } # write_converters = [strip_converter, upcase_converter] # output_string = CSV.generate(write_converters: write_converters) do |csv| # csv << [' foo ', 0] # csv << [' bar ', 1] # csv << [' baz ', 2] # end # output_string # => "FOO,0\nBAR,1\nBAZ,2\n" # # === Character Encodings (M17n or Multilingualization) # # This new CSV parser is m17n savvy. The parser works in the Encoding of the IO # or String object being read from or written to. Your data is never transcoded # (unless you ask Ruby to transcode it for you) and will literally be parsed in # the Encoding it is in. Thus CSV will return Arrays or Rows of Strings in the # Encoding of your data. This is accomplished by transcoding the parser itself # into your Encoding. # # Some transcoding must take place, of course, to accomplish this multiencoding # support. For example, :col_sep, :row_sep, and # :quote_char must be transcoded to match your data. Hopefully this # makes the entire process feel transparent, since CSV's defaults should just # magically work for your data. However, you can set these values manually in # the target Encoding to avoid the translation. # # It's also important to note that while all of CSV's core parser is now # Encoding agnostic, some features are not. For example, the built-in # converters will try to transcode data to UTF-8 before making conversions. # Again, you can provide custom converters that are aware of your Encodings to # avoid this translation. It's just too hard for me to support native # conversions in all of Ruby's Encodings. # # Anyway, the practical side of this is simple: make sure IO and String objects # passed into CSV have the proper Encoding set and everything should just work. # CSV methods that allow you to open IO objects (CSV::foreach(), CSV::open(), # CSV::read(), and CSV::readlines()) do allow you to specify the Encoding. # # One minor exception comes when generating CSV into a String with an Encoding # that is not ASCII compatible. There's no existing data for CSV to use to # prepare itself and thus you will probably need to manually specify the desired # Encoding for most of those cases. It will try to guess using the fields in a # row of output though, when using CSV::generate_line() or Array#to_csv(). # # I try to point out any other Encoding issues in the documentation of methods # as they come up. # # This has been tested to the best of my ability with all non-"dummy" Encodings # Ruby ships with. However, it is brave new code and may have some bugs. # Please feel free to {report}[mailto:james@grayproductions.net] any issues you # find with it. # # source://csv//lib/csv/fields_converter.rb#3 class CSV include ::Enumerable extend ::Forwardable # :call-seq: # CSV.new(string) # CSV.new(io) # CSV.new(string, **options) # CSV.new(io, **options) # # Returns the new \CSV object created using +string+ or +io+ # and the specified +options+. # # - Argument +string+ should be a \String object; # it will be put into a new StringIO object positioned at the beginning. # :include: ../doc/csv/arguments/io.rdoc # - Argument +options+: See: # * {Options for Parsing}[#class-CSV-label-Options+for+Parsing] # * {Options for Generating}[#class-CSV-label-Options+for+Generating] # For performance reasons, the options cannot be overridden # in a \CSV object, so those specified here will endure. # # In addition to the \CSV instance methods, several \IO methods are delegated. # See {Delegated Methods}[#class-CSV-label-Delegated+Methods]. # # --- # # Create a \CSV object from a \String object: # csv = CSV.new('foo,0') # # Create a \CSV object from a \File object: # File.write('t.csv', 'foo,0') # csv = CSV.new(File.open('t.csv')) # # --- # # Raises an exception if the argument is +nil+: # # Raises ArgumentError (Cannot parse nil as CSV): # CSV.new(nil) # # @raise [ArgumentError] # @return [CSV] a new instance of CSV # # source://csv//lib/csv.rb#2034 def initialize(data, col_sep: T.unsafe(nil), row_sep: T.unsafe(nil), quote_char: T.unsafe(nil), field_size_limit: T.unsafe(nil), max_field_size: T.unsafe(nil), converters: T.unsafe(nil), unconverted_fields: T.unsafe(nil), headers: T.unsafe(nil), return_headers: T.unsafe(nil), write_headers: T.unsafe(nil), header_converters: T.unsafe(nil), skip_blanks: T.unsafe(nil), force_quotes: T.unsafe(nil), skip_lines: T.unsafe(nil), liberal_parsing: T.unsafe(nil), internal_encoding: T.unsafe(nil), external_encoding: T.unsafe(nil), encoding: T.unsafe(nil), nil_value: T.unsafe(nil), empty_value: T.unsafe(nil), strip: T.unsafe(nil), quote_empty: T.unsafe(nil), write_converters: T.unsafe(nil), write_nil_value: T.unsafe(nil), write_empty_value: T.unsafe(nil)); end # :call-seq: # csv << row -> self # # Appends a row to +self+. # # - Argument +row+ must be an \Array object or a CSV::Row object. # - The output stream must be open for writing. # # --- # # Append Arrays: # CSV.generate do |csv| # csv << ['foo', 0] # csv << ['bar', 1] # csv << ['baz', 2] # end # => "foo,0\nbar,1\nbaz,2\n" # # Append CSV::Rows: # headers = [] # CSV.generate do |csv| # csv << CSV::Row.new(headers, ['foo', 0]) # csv << CSV::Row.new(headers, ['bar', 1]) # csv << CSV::Row.new(headers, ['baz', 2]) # end # => "foo,0\nbar,1\nbaz,2\n" # # Headers in CSV::Row objects are not appended: # headers = ['Name', 'Count'] # CSV.generate do |csv| # csv << CSV::Row.new(headers, ['foo', 0]) # csv << CSV::Row.new(headers, ['bar', 1]) # csv << CSV::Row.new(headers, ['baz', 2]) # end # => "foo,0\nbar,1\nbaz,2\n" # # --- # # Raises an exception if +row+ is not an \Array or \CSV::Row: # CSV.generate do |csv| # # Raises NoMethodError (undefined method `collect' for :foo:Symbol) # csv << :foo # end # # Raises an exception if the output stream is not opened for writing: # path = 't.csv' # File.write(path, '') # File.open(path) do |file| # CSV.open(file) do |csv| # # Raises IOError (not opened for writing) # csv << ['foo', 0] # end # end # # source://csv//lib/csv.rb#2507 def <<(row); end # :call-seq: # csv << row -> self # # Appends a row to +self+. # # - Argument +row+ must be an \Array object or a CSV::Row object. # - The output stream must be open for writing. # # --- # # Append Arrays: # CSV.generate do |csv| # csv << ['foo', 0] # csv << ['bar', 1] # csv << ['baz', 2] # end # => "foo,0\nbar,1\nbaz,2\n" # # Append CSV::Rows: # headers = [] # CSV.generate do |csv| # csv << CSV::Row.new(headers, ['foo', 0]) # csv << CSV::Row.new(headers, ['bar', 1]) # csv << CSV::Row.new(headers, ['baz', 2]) # end # => "foo,0\nbar,1\nbaz,2\n" # # Headers in CSV::Row objects are not appended: # headers = ['Name', 'Count'] # CSV.generate do |csv| # csv << CSV::Row.new(headers, ['foo', 0]) # csv << CSV::Row.new(headers, ['bar', 1]) # csv << CSV::Row.new(headers, ['baz', 2]) # end # => "foo,0\nbar,1\nbaz,2\n" # # --- # # Raises an exception if +row+ is not an \Array or \CSV::Row: # CSV.generate do |csv| # # Raises NoMethodError (undefined method `collect' for :foo:Symbol) # csv << :foo # end # # Raises an exception if the output stream is not opened for writing: # path = 't.csv' # File.write(path, '') # File.open(path) do |file| # CSV.open(file) do |csv| # # Raises IOError (not opened for writing) # csv << ['foo', 0] # end # end # # source://csv//lib/csv.rb#2507 def add_row(row); end # @return [Boolean] # # source://csv//lib/csv.rb#2396 def binmode?; end # :call-seq: # csv.col_sep -> string # # Returns the encoded column separator; used for parsing and writing; # see {Option +col_sep+}[#class-CSV-label-Option+col_sep]: # CSV.new('').col_sep # => "," # # source://csv//lib/csv.rb#2144 def col_sep; end # :call-seq: # convert(converter_name) -> array_of_procs # convert {|field, field_info| ... } -> array_of_procs # # - With no block, installs a field converter (a \Proc). # - With a block, defines and installs a custom field converter. # - Returns the \Array of installed field converters. # # - Argument +converter_name+, if given, should be the name # of an existing field converter. # # See {Field Converters}[#class-CSV-label-Field+Converters]. # --- # # With no block, installs a field converter: # csv = CSV.new('') # csv.convert(:integer) # csv.convert(:float) # csv.convert(:date) # csv.converters # => [:integer, :float, :date] # # --- # # The block, if given, is called for each field: # - Argument +field+ is the field value. # - Argument +field_info+ is a CSV::FieldInfo object # containing details about the field. # # The examples here assume the prior execution of: # string = "foo,0\nbar,1\nbaz,2\n" # path = 't.csv' # File.write(path, string) # # Example giving a block: # csv = CSV.open(path) # csv.convert {|field, field_info| p [field, field_info]; field.upcase } # csv.read # => [["FOO", "0"], ["BAR", "1"], ["BAZ", "2"]] # # Output: # ["foo", #] # ["0", #] # ["bar", #] # ["1", #] # ["baz", #] # ["2", #] # # The block need not return a \String object: # csv = CSV.open(path) # csv.convert {|field, field_info| field.to_sym } # csv.read # => [[:foo, :"0"], [:bar, :"1"], [:baz, :"2"]] # # If +converter_name+ is given, the block is not called: # csv = CSV.open(path) # csv.convert(:integer) {|field, field_info| fail 'Cannot happen' } # csv.read # => [["foo", 0], ["bar", 1], ["baz", 2]] # # --- # # Raises a parse-time exception if +converter_name+ is not the name of a built-in # field converter: # csv = CSV.open(path) # csv.convert(:nosuch) => [nil] # # Raises NoMethodError (undefined method `arity' for nil:NilClass) # csv.read # # source://csv//lib/csv.rb#2578 def convert(name = T.unsafe(nil), &converter); end # :call-seq: # csv.converters -> array # # Returns an \Array containing field converters; # see {Field Converters}[#class-CSV-label-Field+Converters]: # csv = CSV.new('') # csv.converters # => [] # csv.convert(:integer) # csv.converters # => [:integer] # csv.convert(proc {|x| x.to_s }) # csv.converters # # Notes that you need to call # +Ractor.make_shareable(CSV::Converters)+ on the main Ractor to use # this method. # # source://csv//lib/csv.rb#2217 def converters; end # :call-seq: # csv.each -> enumerator # csv.each {|row| ...} # # Calls the block with each successive row. # The data source must be opened for reading. # # Without headers: # string = "foo,0\nbar,1\nbaz,2\n" # csv = CSV.new(string) # csv.each do |row| # p row # end # Output: # ["foo", "0"] # ["bar", "1"] # ["baz", "2"] # # With headers: # string = "Name,Value\nfoo,0\nbar,1\nbaz,2\n" # csv = CSV.new(string, headers: true) # csv.each do |row| # p row # end # Output: # # # # # --- # # Raises an exception if the source is not opened for reading: # string = "foo,0\nbar,1\nbaz,2\n" # csv = CSV.new(string) # csv.close # # Raises IOError (not opened for reading) # csv.each do |row| # p row # end # # source://csv//lib/csv.rb#2689 def each(&block); end # :call-seq: # csv.encoding -> encoding # # Returns the encoding used for parsing and generating; # see {Character Encodings (M17n or Multilingualization)}[#class-CSV-label-Character+Encodings+-28M17n+or+Multilingualization-29]: # CSV.new('').encoding # => # # # source://csv//lib/csv.rb#2327 def encoding; end # @return [Boolean] # # source://csv//lib/csv.rb#2432 def eof; end # @return [Boolean] # # source://csv//lib/csv.rb#2432 def eof?; end # :call-seq: # csv.field_size_limit -> integer or nil # # Returns the limit for field size; used for parsing; # see {Option +field_size_limit+}[#class-CSV-label-Option+field_size_limit]: # CSV.new('').field_size_limit # => nil # # Deprecated since 3.2.3. Use +max_field_size+ instead. # # source://csv//lib/csv.rb#2176 def field_size_limit; end # @raise [NotImplementedError] # # source://csv//lib/csv.rb#2404 def flock(*args); end # :call-seq: # csv.force_quotes? -> true or false # # Returns the value that determines whether all output fields are to be quoted; # used for generating; # see {Option +force_quotes+}[#class-CSV-label-Option+force_quotes]: # CSV.new('').force_quotes? # => false # # @return [Boolean] # # source://csv//lib/csv.rb#2307 def force_quotes?; end # :call-seq: # csv.shift -> array, csv_row, or nil # # Returns the next row of data as: # - An \Array if no headers are used. # - A CSV::Row object if headers are used. # # The data source must be opened for reading. # # Without headers: # string = "foo,0\nbar,1\nbaz,2\n" # csv = CSV.new(string) # csv.shift # => ["foo", "0"] # csv.shift # => ["bar", "1"] # csv.shift # => ["baz", "2"] # csv.shift # => nil # # With headers: # string = "Name,Value\nfoo,0\nbar,1\nbaz,2\n" # csv = CSV.new(string, headers: true) # csv.shift # => # # csv.shift # => # # csv.shift # => # # csv.shift # => nil # # --- # # Raises an exception if the source is not opened for reading: # string = "foo,0\nbar,1\nbaz,2\n" # csv = CSV.new(string) # csv.close # # Raises IOError (not opened for reading) # csv.shift # # source://csv//lib/csv.rb#2803 def gets; end # The block need not return a \String object: # csv = CSV.open(path, headers: true) # csv.header_convert {|header, field_info| header.to_sym } # table = csv.read # table.headers # => [:Name, :Value] # # If +converter_name+ is given, the block is not called: # csv = CSV.open(path, headers: true) # csv.header_convert(:downcase) {|header, field_info| fail 'Cannot happen' } # table = csv.read # table.headers # => ["name", "value"] # --- # # Raises a parse-time exception if +converter_name+ is not the name of a built-in # field converter: # csv = CSV.open(path, headers: true) # csv.header_convert(:nosuch) # # Raises NoMethodError (undefined method `arity' for nil:NilClass) # csv.read # # source://csv//lib/csv.rb#2644 def header_convert(name = T.unsafe(nil), &converter); end # :call-seq: # csv.header_converters -> array # # Returns an \Array containing header converters; used for parsing; # see {Header Converters}[#class-CSV-label-Header+Converters]: # CSV.new('').header_converters # => [] # # Notes that you need to call # +Ractor.make_shareable(CSV::HeaderConverters)+ on the main Ractor # to use this method. # # source://csv//lib/csv.rb#2283 def header_converters; end # :call-seq: # csv.header_row? -> true or false # # Returns +true+ if the next row to be read is a header row\; # +false+ otherwise. # # Without headers: # string = "foo,0\nbar,1\nbaz,2\n" # csv = CSV.new(string) # csv.header_row? # => false # # With headers: # string = "Name,Value\nfoo,0\nbar,1\nbaz,2\n" # csv = CSV.new(string, headers: true) # csv.header_row? # => true # csv.shift # => # # csv.header_row? # => false # # --- # # Raises an exception if the source is not opened for reading: # string = "foo,0\nbar,1\nbaz,2\n" # csv = CSV.new(string) # csv.close # # Raises IOError (not opened for reading) # csv.header_row? # # @return [Boolean] # # source://csv//lib/csv.rb#2766 def header_row?; end # :call-seq: # csv.headers -> object # # Returns the value that determines whether headers are used; used for parsing; # see {Option +headers+}[#class-CSV-label-Option+headers]: # CSV.new('').headers # => nil # # source://csv//lib/csv.rb#2241 def headers; end # :call-seq: # csv.inspect -> string # # Returns a \String showing certain properties of +self+: # string = "Name,Value\nfoo,0\nbar,1\nbaz,2\n" # csv = CSV.new(string, headers: true) # s = csv.inspect # # source://csv//lib/csv.rb#2825 def inspect; end # @raise [NotImplementedError] # # source://csv//lib/csv.rb#2409 def ioctl(*args); end # :call-seq: # csv.liberal_parsing? -> true or false # # Returns the value that determines whether illegal input is to be handled; used for parsing; # see {Option +liberal_parsing+}[#class-CSV-label-Option+liberal_parsing]: # CSV.new('').liberal_parsing? # => false # # @return [Boolean] # # source://csv//lib/csv.rb#2317 def liberal_parsing?; end # :call-seq: # csv.line -> array # # Returns the line most recently read: # string = "foo,0\nbar,1\nbaz,2\n" # path = 't.csv' # File.write(path, string) # CSV.open(path) do |csv| # csv.each do |row| # p [csv.lineno, csv.line] # end # end # Output: # [1, "foo,0\n"] # [2, "bar,1\n"] # [3, "baz,2\n"] # # source://csv//lib/csv.rb#2382 def line; end # :call-seq: # csv.line_no -> integer # # Returns the count of the rows parsed or generated. # # Parsing: # string = "foo,0\nbar,1\nbaz,2\n" # path = 't.csv' # File.write(path, string) # CSV.open(path) do |csv| # csv.each do |row| # p [csv.lineno, row] # end # end # Output: # [1, ["foo", "0"]] # [2, ["bar", "1"]] # [3, ["baz", "2"]] # # Generating: # CSV.generate do |csv| # p csv.lineno; csv << ['foo', 0] # p csv.lineno; csv << ['bar', 1] # p csv.lineno; csv << ['baz', 2] # end # Output: # 0 # 1 # 2 # # source://csv//lib/csv.rb#2358 def lineno; end # :call-seq: # csv.max_field_size -> integer or nil # # Returns the limit for field size; used for parsing; # see {Option +max_field_size+}[#class-CSV-label-Option+max_field_size]: # CSV.new('').max_field_size # => nil # # Since 3.2.3. # # source://csv//lib/csv.rb#2188 def max_field_size; end # source://csv//lib/csv.rb#2414 def path; end # :call-seq: # csv << row -> self # # Appends a row to +self+. # # - Argument +row+ must be an \Array object or a CSV::Row object. # - The output stream must be open for writing. # # --- # # Append Arrays: # CSV.generate do |csv| # csv << ['foo', 0] # csv << ['bar', 1] # csv << ['baz', 2] # end # => "foo,0\nbar,1\nbaz,2\n" # # Append CSV::Rows: # headers = [] # CSV.generate do |csv| # csv << CSV::Row.new(headers, ['foo', 0]) # csv << CSV::Row.new(headers, ['bar', 1]) # csv << CSV::Row.new(headers, ['baz', 2]) # end # => "foo,0\nbar,1\nbaz,2\n" # # Headers in CSV::Row objects are not appended: # headers = ['Name', 'Count'] # CSV.generate do |csv| # csv << CSV::Row.new(headers, ['foo', 0]) # csv << CSV::Row.new(headers, ['bar', 1]) # csv << CSV::Row.new(headers, ['baz', 2]) # end # => "foo,0\nbar,1\nbaz,2\n" # # --- # # Raises an exception if +row+ is not an \Array or \CSV::Row: # CSV.generate do |csv| # # Raises NoMethodError (undefined method `collect' for :foo:Symbol) # csv << :foo # end # # Raises an exception if the output stream is not opened for writing: # path = 't.csv' # File.write(path, '') # File.open(path) do |file| # CSV.open(file) do |csv| # # Raises IOError (not opened for writing) # csv << ['foo', 0] # end # end # # source://csv//lib/csv.rb#2507 def puts(row); end # :call-seq: # csv.quote_char -> character # # Returns the encoded quote character; used for parsing and writing; # see {Option +quote_char+}[#class-CSV-label-Option+quote_char]: # CSV.new('').quote_char # => "\"" # # source://csv//lib/csv.rb#2164 def quote_char; end # :call-seq: # csv.read -> array or csv_table # # Forms the remaining rows from +self+ into: # - A CSV::Table object, if headers are in use. # - An \Array of Arrays, otherwise. # # The data source must be opened for reading. # # Without headers: # string = "foo,0\nbar,1\nbaz,2\n" # path = 't.csv' # File.write(path, string) # csv = CSV.open(path) # csv.read # => [["foo", "0"], ["bar", "1"], ["baz", "2"]] # # With headers: # string = "Name,Value\nfoo,0\nbar,1\nbaz,2\n" # path = 't.csv' # File.write(path, string) # csv = CSV.open(path, headers: true) # csv.read # => # # # --- # # Raises an exception if the source is not opened for reading: # string = "foo,0\nbar,1\nbaz,2\n" # csv = CSV.new(string) # csv.close # # Raises IOError (not opened for reading) # csv.read # # source://csv//lib/csv.rb#2730 def read; end # :call-seq: # csv.shift -> array, csv_row, or nil # # Returns the next row of data as: # - An \Array if no headers are used. # - A CSV::Row object if headers are used. # # The data source must be opened for reading. # # Without headers: # string = "foo,0\nbar,1\nbaz,2\n" # csv = CSV.new(string) # csv.shift # => ["foo", "0"] # csv.shift # => ["bar", "1"] # csv.shift # => ["baz", "2"] # csv.shift # => nil # # With headers: # string = "Name,Value\nfoo,0\nbar,1\nbaz,2\n" # csv = CSV.new(string, headers: true) # csv.shift # => # # csv.shift # => # # csv.shift # => # # csv.shift # => nil # # --- # # Raises an exception if the source is not opened for reading: # string = "foo,0\nbar,1\nbaz,2\n" # csv = CSV.new(string) # csv.close # # Raises IOError (not opened for reading) # csv.shift # # source://csv//lib/csv.rb#2803 def readline; end # :call-seq: # csv.read -> array or csv_table # # Forms the remaining rows from +self+ into: # - A CSV::Table object, if headers are in use. # - An \Array of Arrays, otherwise. # # The data source must be opened for reading. # # Without headers: # string = "foo,0\nbar,1\nbaz,2\n" # path = 't.csv' # File.write(path, string) # csv = CSV.open(path) # csv.read # => [["foo", "0"], ["bar", "1"], ["baz", "2"]] # # With headers: # string = "Name,Value\nfoo,0\nbar,1\nbaz,2\n" # path = 't.csv' # File.write(path, string) # csv = CSV.open(path, headers: true) # csv.read # => # # # --- # # Raises an exception if the source is not opened for reading: # string = "foo,0\nbar,1\nbaz,2\n" # csv = CSV.new(string) # csv.close # # Raises IOError (not opened for reading) # csv.read # # source://csv//lib/csv.rb#2730 def readlines; end # :call-seq: # csv.return_headers? -> true or false # # Returns the value that determines whether headers are to be returned; used for parsing; # see {Option +return_headers+}[#class-CSV-label-Option+return_headers]: # CSV.new('').return_headers? # => false # # @return [Boolean] # # source://csv//lib/csv.rb#2259 def return_headers?; end # Rewinds the underlying IO object and resets CSV's lineno() counter. # # source://csv//lib/csv.rb#2447 def rewind; end # :call-seq: # csv.row_sep -> string # # Returns the encoded row separator; used for parsing and writing; # see {Option +row_sep+}[#class-CSV-label-Option+row_sep]: # CSV.new('').row_sep # => "\n" # # source://csv//lib/csv.rb#2154 def row_sep; end # :call-seq: # csv.shift -> array, csv_row, or nil # # Returns the next row of data as: # - An \Array if no headers are used. # - A CSV::Row object if headers are used. # # The data source must be opened for reading. # # Without headers: # string = "foo,0\nbar,1\nbaz,2\n" # csv = CSV.new(string) # csv.shift # => ["foo", "0"] # csv.shift # => ["bar", "1"] # csv.shift # => ["baz", "2"] # csv.shift # => nil # # With headers: # string = "Name,Value\nfoo,0\nbar,1\nbaz,2\n" # csv = CSV.new(string, headers: true) # csv.shift # => # # csv.shift # => # # csv.shift # => # # csv.shift # => nil # # --- # # Raises an exception if the source is not opened for reading: # string = "foo,0\nbar,1\nbaz,2\n" # csv = CSV.new(string) # csv.close # # Raises IOError (not opened for reading) # csv.shift # # source://csv//lib/csv.rb#2803 def shift; end # :call-seq: # csv.skip_blanks? -> true or false # # Returns the value that determines whether blank lines are to be ignored; used for parsing; # see {Option +skip_blanks+}[#class-CSV-label-Option+skip_blanks]: # CSV.new('').skip_blanks? # => false # # @return [Boolean] # # source://csv//lib/csv.rb#2296 def skip_blanks?; end # :call-seq: # csv.skip_lines -> regexp or nil # # Returns the \Regexp used to identify comment lines; used for parsing; # see {Option +skip_lines+}[#class-CSV-label-Option+skip_lines]: # CSV.new('').skip_lines # => nil # # source://csv//lib/csv.rb#2198 def skip_lines; end # @raise [NotImplementedError] # # source://csv//lib/csv.rb#2418 def stat(*args); end # @raise [NotImplementedError] # # source://csv//lib/csv.rb#2423 def to_i; end # source://csv//lib/csv.rb#2428 def to_io; end # :call-seq: # csv.unconverted_fields? -> object # # Returns the value that determines whether unconverted fields are to be # available; used for parsing; # see {Option +unconverted_fields+}[#class-CSV-label-Option+unconverted_fields]: # CSV.new('').unconverted_fields? # => nil # # @return [Boolean] # # source://csv//lib/csv.rb#2231 def unconverted_fields?; end # :call-seq: # csv.write_headers? -> true or false # # Returns the value that determines whether headers are to be written; used for generating; # see {Option +write_headers+}[#class-CSV-label-Option+write_headers]: # CSV.new('').write_headers? # => nil # # @return [Boolean] # # source://csv//lib/csv.rb#2269 def write_headers?; end private # source://csv//lib/csv.rb#2957 def build_fields_converter(initial_converters, options); end # source://csv//lib/csv.rb#2939 def build_header_fields_converter; end # source://csv//lib/csv.rb#2927 def build_parser_fields_converter; end # source://csv//lib/csv.rb#2952 def build_writer_fields_converter; end # Processes +fields+ with @converters, or @header_converters # if +headers+ is passed as +true+, returning the converted field set. Any # converter that changes the field into something other than a String halts # the pipeline of conversion for that field. This is primarily an efficiency # shortcut. # # source://csv//lib/csv.rb#2902 def convert_fields(fields, headers = T.unsafe(nil)); end # source://csv//lib/csv.rb#2865 def determine_encoding(encoding, internal_encoding); end # source://csv//lib/csv.rb#2935 def header_fields_converter; end # source://csv//lib/csv.rb#2880 def normalize_converters(converters); end # source://csv//lib/csv.rb#2965 def parser; end # source://csv//lib/csv.rb#2974 def parser_enumerator; end # source://csv//lib/csv.rb#2923 def parser_fields_converter; end # source://csv//lib/csv.rb#2969 def parser_options; end # Returns the encoding of the internal IO object. # # source://csv//lib/csv.rb#2913 def raw_encoding; end # source://csv//lib/csv.rb#2978 def writer; end # source://csv//lib/csv.rb#2948 def writer_fields_converter; end # source://csv//lib/csv.rb#2982 def writer_options; end class << self # :call-seq: # filter(in_string_or_io, **options) {|row| ... } -> array_of_arrays or csv_table # filter(in_string_or_io, out_string_or_io, **options) {|row| ... } -> array_of_arrays or csv_table # filter(**options) {|row| ... } -> array_of_arrays or csv_table # # - Parses \CSV from a source (\String, \IO stream, or ARGF). # - Calls the given block with each parsed row: # - Without headers, each row is an \Array. # - With headers, each row is a CSV::Row. # - Generates \CSV to an output (\String, \IO stream, or STDOUT). # - Returns the parsed source: # - Without headers, an \Array of \Arrays. # - With headers, a CSV::Table. # # When +in_string_or_io+ is given, but not +out_string_or_io+, # parses from the given +in_string_or_io+ # and generates to STDOUT. # # \String input without headers: # # in_string = "foo,0\nbar,1\nbaz,2" # CSV.filter(in_string) do |row| # row[0].upcase! # row[1] = - row[1].to_i # end # => [["FOO", 0], ["BAR", -1], ["BAZ", -2]] # # Output (to STDOUT): # # FOO,0 # BAR,-1 # BAZ,-2 # # \String input with headers: # # in_string = "Name,Value\nfoo,0\nbar,1\nbaz,2" # CSV.filter(in_string, headers: true) do |row| # row[0].upcase! # row[1] = - row[1].to_i # end # => # # # Output (to STDOUT): # # Name,Value # FOO,0 # BAR,-1 # BAZ,-2 # # \IO stream input without headers: # # File.write('t.csv', "foo,0\nbar,1\nbaz,2") # File.open('t.csv') do |in_io| # CSV.filter(in_io) do |row| # row[0].upcase! # row[1] = - row[1].to_i # end # end # => [["FOO", 0], ["BAR", -1], ["BAZ", -2]] # # Output (to STDOUT): # # FOO,0 # BAR,-1 # BAZ,-2 # # \IO stream input with headers: # # File.write('t.csv', "Name,Value\nfoo,0\nbar,1\nbaz,2") # File.open('t.csv') do |in_io| # CSV.filter(in_io, headers: true) do |row| # row[0].upcase! # row[1] = - row[1].to_i # end # end # => # # # Output (to STDOUT): # # Name,Value # FOO,0 # BAR,-1 # BAZ,-2 # # When both +in_string_or_io+ and +out_string_or_io+ are given, # parses from +in_string_or_io+ and generates to +out_string_or_io+. # # \String output without headers: # # in_string = "foo,0\nbar,1\nbaz,2" # out_string = '' # CSV.filter(in_string, out_string) do |row| # row[0].upcase! # row[1] = - row[1].to_i # end # => [["FOO", 0], ["BAR", -1], ["BAZ", -2]] # out_string # => "FOO,0\nBAR,-1\nBAZ,-2\n" # # \String output with headers: # # in_string = "Name,Value\nfoo,0\nbar,1\nbaz,2" # out_string = '' # CSV.filter(in_string, out_string, headers: true) do |row| # row[0].upcase! # row[1] = - row[1].to_i # end # => # # out_string # => "Name,Value\nFOO,0\nBAR,-1\nBAZ,-2\n" # # \IO stream output without headers: # # in_string = "foo,0\nbar,1\nbaz,2" # File.open('t.csv', 'w') do |out_io| # CSV.filter(in_string, out_io) do |row| # row[0].upcase! # row[1] = - row[1].to_i # end # end # => [["FOO", 0], ["BAR", -1], ["BAZ", -2]] # File.read('t.csv') # => "FOO,0\nBAR,-1\nBAZ,-2\n" # # \IO stream output with headers: # # in_string = "Name,Value\nfoo,0\nbar,1\nbaz,2" # File.open('t.csv', 'w') do |out_io| # CSV.filter(in_string, out_io, headers: true) do |row| # row[0].upcase! # row[1] = - row[1].to_i # end # end # => # # File.read('t.csv') # => "Name,Value\nFOO,0\nBAR,-1\nBAZ,-2\n" # # When neither +in_string_or_io+ nor +out_string_or_io+ given, # parses from {ARGF}[rdoc-ref:ARGF] # and generates to STDOUT. # # Without headers: # # # Put Ruby code into a file. # ruby = <<-EOT # require 'csv' # CSV.filter do |row| # row[0].upcase! # row[1] = - row[1].to_i # end # EOT # File.write('t.rb', ruby) # # Put some CSV into a file. # File.write('t.csv', "foo,0\nbar,1\nbaz,2") # # Run the Ruby code with CSV filename as argument. # system(Gem.ruby, "t.rb", "t.csv") # # Output (to STDOUT): # # FOO,0 # BAR,-1 # BAZ,-2 # # With headers: # # # Put Ruby code into a file. # ruby = <<-EOT # require 'csv' # CSV.filter(headers: true) do |row| # row[0].upcase! # row[1] = - row[1].to_i # end # EOT # File.write('t.rb', ruby) # # Put some CSV into a file. # File.write('t.csv', "Name,Value\nfoo,0\nbar,1\nbaz,2") # # Run the Ruby code with CSV filename as argument. # system(Gem.ruby, "t.rb", "t.csv") # # Output (to STDOUT): # # Name,Value # FOO,0 # BAR,-1 # BAZ,-2 # # Arguments: # # * Argument +in_string_or_io+ must be a \String or an \IO stream. # * Argument +out_string_or_io+ must be a \String or an \IO stream. # * Arguments **options must be keyword options. # # - Each option defined as an {option for parsing}[#class-CSV-label-Options+for+Parsing] # is used for parsing the filter input. # - Each option defined as an {option for generating}[#class-CSV-label-Options+for+Generating] # is used for generator the filter input. # # However, there are three options that may be used for both parsing and generating: # +col_sep+, +quote_char+, and +row_sep+. # # Therefore for method +filter+ (and method +filter+ only), # there are special options that allow these parsing and generating options # to be specified separately: # # - Options +input_col_sep+ and +output_col_sep+ # (and their aliases +in_col_sep+ and +out_col_sep+) # specify the column separators for parsing and generating. # - Options +input_quote_char+ and +output_quote_char+ # (and their aliases +in_quote_char+ and +out_quote_char+) # specify the quote characters for parsing and generting. # - Options +input_row_sep+ and +output_row_sep+ # (and their aliases +in_row_sep+ and +out_row_sep+) # specify the row separators for parsing and generating. # # Example options (for column separators): # # CSV.filter # Default for both parsing and generating. # CSV.filter(in_col_sep: ';') # ';' for parsing, default for generating. # CSV.filter(out_col_sep: '|') # Default for parsing, '|' for generating. # CSV.filter(in_col_sep: ';', out_col_sep: '|') # ';' for parsing, '|' for generating. # # Note that for a special option (e.g., +input_col_sep+) # and its corresponding "regular" option (e.g., +col_sep+), # the two are mutually overriding. # # Another example (possibly surprising): # # CSV.filter(in_col_sep: ';', col_sep: '|') # '|' for both parsing(!) and generating. # # source://csv//lib/csv.rb#1259 def filter(input = T.unsafe(nil), output = T.unsafe(nil), **options); end # :call-seq: # foreach(path_or_io, mode='r', **options) {|row| ... ) # foreach(path_or_io, mode='r', **options) -> new_enumerator # # Calls the block with each row read from source +path_or_io+. # # \Path input without headers: # # string = "foo,0\nbar,1\nbaz,2\n" # in_path = 't.csv' # File.write(in_path, string) # CSV.foreach(in_path) {|row| p row } # # Output: # # ["foo", "0"] # ["bar", "1"] # ["baz", "2"] # # \Path input with headers: # # string = "Name,Value\nfoo,0\nbar,1\nbaz,2\n" # in_path = 't.csv' # File.write(in_path, string) # CSV.foreach(in_path, headers: true) {|row| p row } # # Output: # # # # # # \IO stream input without headers: # # string = "foo,0\nbar,1\nbaz,2\n" # path = 't.csv' # File.write(path, string) # File.open('t.csv') do |in_io| # CSV.foreach(in_io) {|row| p row } # end # # Output: # # ["foo", "0"] # ["bar", "1"] # ["baz", "2"] # # \IO stream input with headers: # # string = "Name,Value\nfoo,0\nbar,1\nbaz,2\n" # path = 't.csv' # File.write(path, string) # File.open('t.csv') do |in_io| # CSV.foreach(in_io, headers: true) {|row| p row } # end # # Output: # # # # # # With no block given, returns an \Enumerator: # # string = "foo,0\nbar,1\nbaz,2\n" # path = 't.csv' # File.write(path, string) # CSV.foreach(path) # => # # # Arguments: # * Argument +path_or_io+ must be a file path or an \IO stream. # * Argument +mode+, if given, must be a \File mode. # See {Access Modes}[https://docs.ruby-lang.org/en/master/File.html#class-File-label-Access+Modes]. # * Arguments **options must be keyword options. # See {Options for Parsing}[#class-CSV-label-Options+for+Parsing]. # * This method optionally accepts an additional :encoding option # that you can use to specify the Encoding of the data read from +path+ or +io+. # You must provide this unless your data is in the encoding # given by Encoding::default_external. # Parsing will use this to determine how to parse the data. # You may provide a second Encoding to # have the data transcoded as it is read. For example, # would read +UTF-32BE+ data from the file # but transcode it to +UTF-8+ before parsing. # # source://csv//lib/csv.rb#1389 def foreach(path, mode = T.unsafe(nil), **options, &block); end # :call-seq: # generate(csv_string, **options) {|csv| ... } # generate(**options) {|csv| ... } # # * Argument +csv_string+, if given, must be a \String object; # defaults to a new empty \String. # * Arguments +options+, if given, should be generating options. # See {Options for Generating}[#class-CSV-label-Options+for+Generating]. # # --- # # Creates a new \CSV object via CSV.new(csv_string, **options); # calls the block with the \CSV object, which the block may modify; # returns the \String generated from the \CSV object. # # Note that a passed \String *is* modified by this method. # Pass csv_string.dup if the \String must be preserved. # # This method has one additional option: :encoding, # which sets the base Encoding for the output if no no +str+ is specified. # CSV needs this hint if you plan to output non-ASCII compatible data. # # --- # # Add lines: # input_string = "foo,0\nbar,1\nbaz,2\n" # output_string = CSV.generate(input_string) do |csv| # csv << ['bat', 3] # csv << ['bam', 4] # end # output_string # => "foo,0\nbar,1\nbaz,2\nbat,3\nbam,4\n" # input_string # => "foo,0\nbar,1\nbaz,2\nbat,3\nbam,4\n" # output_string.equal?(input_string) # => true # Same string, modified # # Add lines into new string, preserving old string: # input_string = "foo,0\nbar,1\nbaz,2\n" # output_string = CSV.generate(input_string.dup) do |csv| # csv << ['bat', 3] # csv << ['bam', 4] # end # output_string # => "foo,0\nbar,1\nbaz,2\nbat,3\nbam,4\n" # input_string # => "foo,0\nbar,1\nbaz,2\n" # output_string.equal?(input_string) # => false # Different strings # # Create lines from nothing: # output_string = CSV.generate do |csv| # csv << ['foo', 0] # csv << ['bar', 1] # csv << ['baz', 2] # end # output_string # => "foo,0\nbar,1\nbaz,2\n" # # --- # # Raises an exception if +csv_string+ is not a \String object: # # Raises TypeError (no implicit conversion of Integer into String) # CSV.generate(0) # # @yield [csv] # # source://csv//lib/csv.rb#1455 def generate(str = T.unsafe(nil), **options); end # :call-seq: # CSV.generate_line(ary) # CSV.generate_line(ary, **options) # # Returns the \String created by generating \CSV from +ary+ # using the specified +options+. # # Argument +ary+ must be an \Array. # # Special options: # * Option :row_sep defaults to "\n"> on Ruby 3.0 or later # and $INPUT_RECORD_SEPARATOR ($/) otherwise.: # $INPUT_RECORD_SEPARATOR # => "\n" # * This method accepts an additional option, :encoding, which sets the base # Encoding for the output. This method will try to guess your Encoding from # the first non-+nil+ field in +row+, if possible, but you may need to use # this parameter as a backup plan. # # For other +options+, # see {Options for Generating}[#class-CSV-label-Options+for+Generating]. # # --- # # Returns the \String generated from an \Array: # CSV.generate_line(['foo', '0']) # => "foo,0\n" # # --- # # Raises an exception if +ary+ is not an \Array: # # Raises NoMethodError (undefined method `find' for :foo:Symbol) # CSV.generate_line(:foo) # # source://csv//lib/csv.rb#1503 def generate_line(row, **options); end # :call-seq: # CSV.generate_lines(rows) # CSV.generate_lines(rows, **options) # # Returns the \String created by generating \CSV from # using the specified +options+. # # Argument +rows+ must be an \Array of row. Row is \Array of \String or \CSV::Row. # # Special options: # * Option :row_sep defaults to "\n" on Ruby 3.0 or later # and $INPUT_RECORD_SEPARATOR ($/) otherwise.: # $INPUT_RECORD_SEPARATOR # => "\n" # * This method accepts an additional option, :encoding, which sets the base # Encoding for the output. This method will try to guess your Encoding from # the first non-+nil+ field in +row+, if possible, but you may need to use # this parameter as a backup plan. # # For other +options+, # see {Options for Generating}[#class-CSV-label-Options+for+Generating]. # # --- # # Returns the \String generated from an # CSV.generate_lines([['foo', '0'], ['bar', '1'], ['baz', '2']]) # => "foo,0\nbar,1\nbaz,2\n" # # --- # # Raises an exception # # Raises NoMethodError (undefined method `each' for :foo:Symbol) # CSV.generate_lines(:foo) # # source://csv//lib/csv.rb#1558 def generate_lines(rows, **options); end # :call-seq: # instance(string, **options) # instance(io = $stdout, **options) # instance(string, **options) {|csv| ... } # instance(io = $stdout, **options) {|csv| ... } # # Creates or retrieves cached \CSV objects. # For arguments and options, see CSV.new. # # This API is not Ractor-safe. # # --- # # With no block given, returns a \CSV object. # # The first call to +instance+ creates and caches a \CSV object: # s0 = 's0' # csv0 = CSV.instance(s0) # csv0.class # => CSV # # Subsequent calls to +instance+ with that _same_ +string+ or +io+ # retrieve that same cached object: # csv1 = CSV.instance(s0) # csv1.class # => CSV # csv1.equal?(csv0) # => true # Same CSV object # # A subsequent call to +instance+ with a _different_ +string+ or +io+ # creates and caches a _different_ \CSV object. # s1 = 's1' # csv2 = CSV.instance(s1) # csv2.equal?(csv0) # => false # Different CSV object # # All the cached objects remains available: # csv3 = CSV.instance(s0) # csv3.equal?(csv0) # true # Same CSV object # csv4 = CSV.instance(s1) # csv4.equal?(csv2) # true # Same CSV object # # --- # # When a block is given, calls the block with the created or retrieved # \CSV object; returns the block's return value: # CSV.instance(s0) {|csv| :foo } # => :foo # # source://csv//lib/csv.rb#1026 def instance(data = T.unsafe(nil), **options); end # :call-seq: # open(path_or_io, mode = "rb", **options ) -> new_csv # open(path_or_io, mode = "rb", **options ) { |csv| ... } -> object # # possible options elements: # keyword form: # :invalid => nil # raise error on invalid byte sequence (default) # :invalid => :replace # replace invalid byte sequence # :undef => :replace # replace undefined conversion # :replace => string # replacement string ("?" or "\uFFFD" if not specified) # # * Argument +path_or_io+, must be a file path or an \IO stream. # :include: ../doc/csv/arguments/io.rdoc # * Argument +mode+, if given, must be a \File mode. # See {Access Modes}[https://docs.ruby-lang.org/en/master/File.html#class-File-label-Access+Modes]. # * Arguments **options must be keyword options. # See {Options for Generating}[#class-CSV-label-Options+for+Generating]. # * This method optionally accepts an additional :encoding option # that you can use to specify the Encoding of the data read from +path+ or +io+. # You must provide this unless your data is in the encoding # given by Encoding::default_external. # Parsing will use this to determine how to parse the data. # You may provide a second Encoding to # have the data transcoded as it is read. For example, # would read +UTF-32BE+ data from the file # but transcode it to +UTF-8+ before parsing. # # --- # # These examples assume prior execution of: # string = "foo,0\nbar,1\nbaz,2\n" # path = 't.csv' # File.write(path, string) # # string_io = StringIO.new # string_io << "foo,0\nbar,1\nbaz,2\n" # # --- # # With no block given, returns a new \CSV object. # # Create a \CSV object using a file path: # csv = CSV.open(path) # # Create a \CSV object using an open \File: # csv = CSV.open(File.open(path)) # # Create a \CSV object using a \StringIO: # csv = CSV.open(string_io) # --- # # With a block given, calls the block with the created \CSV object; # returns the block's return value: # # Using a file path: # csv = CSV.open(path) {|csv| p csv} # Output: # # Using an open \File: # csv = CSV.open(File.open(path)) {|csv| p csv} # Output: # # Using a \StringIO: # csv = CSV.open(string_io) {|csv| p csv} # Output: # --- # # Raises an exception if the argument is not a \String object or \IO object: # # Raises TypeError (no implicit conversion of Symbol into String) # CSV.open(:foo) # # source://csv//lib/csv.rb#1647 def open(filename_or_io, mode = T.unsafe(nil), **options); end # :call-seq: # parse(string) -> array_of_arrays # parse(io) -> array_of_arrays # parse(string, headers: ..., **options) -> csv_table # parse(io, headers: ..., **options) -> csv_table # parse(string, **options) {|row| ... } # parse(io, **options) {|row| ... } # # Parses +string+ or +io+ using the specified +options+. # # - Argument +string+ should be a \String object; # it will be put into a new StringIO object positioned at the beginning. # :include: ../doc/csv/arguments/io.rdoc # - Argument +options+: see {Options for Parsing}[#class-CSV-label-Options+for+Parsing] # # ====== Without Option +headers+ # # Without {option +headers+}[#class-CSV-label-Option+headers] case. # # These examples assume prior execution of: # string = "foo,0\nbar,1\nbaz,2\n" # path = 't.csv' # File.write(path, string) # # --- # # With no block given, returns an \Array of Arrays formed from the source. # # Parse a \String: # a_of_a = CSV.parse(string) # a_of_a # => [["foo", "0"], ["bar", "1"], ["baz", "2"]] # # Parse an open \File: # a_of_a = File.open(path) do |file| # CSV.parse(file) # end # a_of_a # => [["foo", "0"], ["bar", "1"], ["baz", "2"]] # # --- # # With a block given, calls the block with each parsed row: # # Parse a \String: # CSV.parse(string) {|row| p row } # # Output: # ["foo", "0"] # ["bar", "1"] # ["baz", "2"] # # Parse an open \File: # File.open(path) do |file| # CSV.parse(file) {|row| p row } # end # # Output: # ["foo", "0"] # ["bar", "1"] # ["baz", "2"] # # ====== With Option +headers+ # # With {option +headers+}[#class-CSV-label-Option+headers] case. # # These examples assume prior execution of: # string = "Name,Count\nfoo,0\nbar,1\nbaz,2\n" # path = 't.csv' # File.write(path, string) # # --- # # With no block given, returns a CSV::Table object formed from the source. # # Parse a \String: # csv_table = CSV.parse(string, headers: ['Name', 'Count']) # csv_table # => # # # Parse an open \File: # csv_table = File.open(path) do |file| # CSV.parse(file, headers: ['Name', 'Count']) # end # csv_table # => # # # --- # # With a block given, calls the block with each parsed row, # which has been formed into a CSV::Row object: # # Parse a \String: # CSV.parse(string, headers: ['Name', 'Count']) {|row| p row } # # Output: # # # # # # # # Parse an open \File: # File.open(path) do |file| # CSV.parse(file, headers: ['Name', 'Count']) {|row| p row } # end # # Output: # # # # # # # # --- # # Raises an exception if the argument is not a \String object or \IO object: # # Raises NoMethodError (undefined method `close' for :foo:Symbol) # CSV.parse(:foo) # # --- # # Please make sure if your text contains \BOM or not. CSV.parse will not remove # \BOM automatically. You might want to remove \BOM before calling CSV.parse : # # remove BOM on calling File.open # CSV.parse(file, headers: true) do |row| # # you can get value by column name because BOM is removed # p row['Name'] # end # end # # Output: # # "foo" # # "bar" # # "baz" # # source://csv//lib/csv.rb#1825 def parse(str, **options, &block); end # :call-seq: # CSV.parse_line(string) -> new_array or nil # CSV.parse_line(io) -> new_array or nil # CSV.parse_line(string, **options) -> new_array or nil # CSV.parse_line(io, **options) -> new_array or nil # CSV.parse_line(string, headers: true, **options) -> csv_row or nil # CSV.parse_line(io, headers: true, **options) -> csv_row or nil # # Returns the data created by parsing the first line of +string+ or +io+ # using the specified +options+. # # - Argument +string+ should be a \String object; # it will be put into a new StringIO object positioned at the beginning. # :include: ../doc/csv/arguments/io.rdoc # - Argument +options+: see {Options for Parsing}[#class-CSV-label-Options+for+Parsing] # # ====== Without Option +headers+ # # Without option +headers+, returns the first row as a new \Array. # # These examples assume prior execution of: # string = "foo,0\nbar,1\nbaz,2\n" # path = 't.csv' # File.write(path, string) # # Parse the first line from a \String object: # CSV.parse_line(string) # => ["foo", "0"] # # Parse the first line from a File object: # File.open(path) do |file| # CSV.parse_line(file) # => ["foo", "0"] # end # => ["foo", "0"] # # Returns +nil+ if the argument is an empty \String: # CSV.parse_line('') # => nil # # ====== With Option +headers+ # # With {option +headers+}[#class-CSV-label-Option+headers], # returns the first row as a CSV::Row object. # # These examples assume prior execution of: # string = "Name,Count\nfoo,0\nbar,1\nbaz,2\n" # path = 't.csv' # File.write(path, string) # # Parse the first line from a \String object: # CSV.parse_line(string, headers: true) # => # # # Parse the first line from a File object: # File.open(path) do |file| # CSV.parse_line(file, headers: true) # end # => # # # --- # # Raises an exception if the argument is +nil+: # # Raises ArgumentError (Cannot parse nil as CSV): # CSV.parse_line(nil) # # source://csv//lib/csv.rb#1898 def parse_line(line, **options); end # :call-seq: # read(source, **options) -> array_of_arrays # read(source, headers: true, **options) -> csv_table # # Opens the given +source+ with the given +options+ (see CSV.open), # reads the source (see CSV#read), and returns the result, # which will be either an \Array of Arrays or a CSV::Table. # # Without headers: # string = "foo,0\nbar,1\nbaz,2\n" # path = 't.csv' # File.write(path, string) # CSV.read(path) # => [["foo", "0"], ["bar", "1"], ["baz", "2"]] # # With headers: # string = "Name,Value\nfoo,0\nbar,1\nbaz,2\n" # path = 't.csv' # File.write(path, string) # CSV.read(path, headers: true) # => # # # source://csv//lib/csv.rb#1922 def read(path, **options); end # :call-seq: # CSV.readlines(source, **options) # # Alias for CSV.read. # # source://csv//lib/csv.rb#1930 def readlines(path, **options); end # :call-seq: # CSV.table(source, **options) # # Calls CSV.read with +source+, +options+, and certain default options: # - +headers+: +true+ # - +converters+: +:numeric+ # - +header_converters+: +:symbol+ # # Returns a CSV::Table object. # # Example: # string = "Name,Value\nfoo,0\nbar,1\nbaz,2\n" # path = 't.csv' # File.write(path, string) # CSV.table(path) # => # # # source://csv//lib/csv.rb#1949 def table(path, **options); end private # source://csv//lib/csv.rb#1990 def create_stringio(str, mode, opts); end # source://csv//lib/csv.rb#1963 def may_enable_bom_detection_automatically(filename_or_io, mode, options, file_opts); end end end # The encoding used by all converters. # # source://csv//lib/csv.rb#895 CSV::ConverterEncoding = T.let(T.unsafe(nil), Encoding) # A \Hash containing the names and \Procs for the built-in field converters. # See {Built-In Field Converters}[#class-CSV-label-Built-In+Field+Converters]. # # This \Hash is intentionally left unfrozen, and may be extended with # custom field converters. # See {Custom Field Converters}[#class-CSV-label-Custom+Field+Converters]. # # source://csv//lib/csv.rb#903 CSV::Converters = T.let(T.unsafe(nil), Hash) # A Regexp used to find and convert some common Date formats. # # source://csv//lib/csv.rb#884 CSV::DateMatcher = T.let(T.unsafe(nil), Regexp) # A Regexp used to find and convert some common (Date)Time formats. # # source://csv//lib/csv.rb#887 CSV::DateTimeMatcher = T.let(T.unsafe(nil), Regexp) # Note: Don't use this class directly. This is an internal class. # # source://csv//lib/csv/fields_converter.rb#5 class CSV::FieldsConverter include ::Enumerable # A CSV::FieldsConverter is a data structure for storing the # fields converter properties to be passed as a parameter # when parsing a new file (e.g. CSV::Parser.new(@io, parser_options)) # # @return [FieldsConverter] a new instance of FieldsConverter # # source://csv//lib/csv/fields_converter.rb#20 def initialize(options = T.unsafe(nil)); end # source://csv//lib/csv/fields_converter.rb#30 def add_converter(name = T.unsafe(nil), &converter); end # source://csv//lib/csv/fields_converter.rb#54 def convert(fields, headers, lineno, quoted_fields = T.unsafe(nil)); end # source://csv//lib/csv/fields_converter.rb#46 def each(&block); end # @return [Boolean] # # source://csv//lib/csv/fields_converter.rb#50 def empty?; end private # source://csv//lib/csv/fields_converter.rb#92 def builtin_converters; end # @return [Boolean] # # source://csv//lib/csv/fields_converter.rb#87 def need_convert?; end # @return [Boolean] # # source://csv//lib/csv/fields_converter.rb#83 def need_static_convert?; end end # source://csv//lib/csv/fields_converter.rb#8 CSV::FieldsConverter::NO_QUOTED_FIELDS = T.let(T.unsafe(nil), Array) # A \Hash containing the names and \Procs for the built-in header converters. # See {Built-In Header Converters}[#class-CSV-label-Built-In+Header+Converters]. # # This \Hash is intentionally left unfrozen, and may be extended with # custom field converters. # See {Custom Header Converters}[#class-CSV-label-Custom+Header+Converters]. # # source://csv//lib/csv.rb#944 CSV::HeaderConverters = T.let(T.unsafe(nil), Hash) # source://csv//lib/csv/input_record_separator.rb#5 module CSV::InputRecordSeparator class << self # source://csv//lib/csv/input_record_separator.rb#8 def value; end end end # The error thrown when the parser encounters invalid encoding in CSV. # # source://csv//lib/csv.rb#862 class CSV::InvalidEncodingError < ::CSV::MalformedCSVError # @return [InvalidEncodingError] a new instance of InvalidEncodingError # # source://csv//lib/csv.rb#864 def initialize(encoding, line_number); end # Returns the value of attribute encoding. # # source://csv//lib/csv.rb#863 def encoding; end end # The error thrown when the parser encounters illegal CSV formatting. # # source://csv//lib/csv.rb#852 class CSV::MalformedCSVError < ::RuntimeError # @return [MalformedCSVError] a new instance of MalformedCSVError # # source://csv//lib/csv.rb#855 def initialize(message, line_number); end # Returns the value of attribute line_number. # # source://csv//lib/csv.rb#853 def line_number; end # Returns the value of attribute line_number. # # source://csv//lib/csv.rb#853 def lineno; end end # Note: Don't use this class directly. This is an internal class. # # source://csv//lib/csv/parser.rb#11 class CSV::Parser # @return [Parser] a new instance of Parser # # source://csv//lib/csv/parser.rb#348 def initialize(input, options); end # source://csv//lib/csv/parser.rb#356 def column_separator; end # source://csv//lib/csv/parser.rb#368 def field_size_limit; end # @return [Boolean] # # source://csv//lib/csv/parser.rb#388 def header_row?; end # source://csv//lib/csv/parser.rb#384 def headers; end # @return [Boolean] # # source://csv//lib/csv/parser.rb#400 def liberal_parsing?; end # source://csv//lib/csv/parser.rb#408 def line; end # source://csv//lib/csv/parser.rb#404 def lineno; end # source://csv//lib/csv/parser.rb#372 def max_field_size; end # source://csv//lib/csv/parser.rb#412 def parse(&block); end # source://csv//lib/csv/parser.rb#364 def quote_character; end # @return [Boolean] # # source://csv//lib/csv/parser.rb#392 def return_headers?; end # source://csv//lib/csv/parser.rb#360 def row_separator; end # @return [Boolean] # # source://csv//lib/csv/parser.rb#396 def skip_blanks?; end # source://csv//lib/csv/parser.rb#376 def skip_lines; end # @return [Boolean] # # source://csv//lib/csv/parser.rb#380 def unconverted_fields?; end # @return [Boolean] # # source://csv//lib/csv/parser.rb#447 def use_headers?; end private # This method injects an instance variable unconverted_fields into # +row+ and an accessor method for +row+ called unconverted_fields(). The # variable is set to the contents of +fields+. # # source://csv//lib/csv/parser.rb#1294 def add_unconverted_fields(row, fields); end # source://csv//lib/csv/parser.rb#806 def adjust_headers(headers, quoted_fields); end # source://csv//lib/csv/parser.rb#881 def build_scanner; end # source://csv//lib/csv/parser.rb#728 def detect_row_separator(sample, cr, lf); end # @yield [row] # # source://csv//lib/csv/parser.rb#1265 def emit_row(row, quoted_fields = T.unsafe(nil), &block); end # source://csv//lib/csv/parser.rb#1250 def ignore_broken_line; end # source://csv//lib/csv/parser.rb#758 def last_line; end # @return [Boolean] # # source://csv//lib/csv/parser.rb#823 def may_quoted?; end # source://csv//lib/csv/parser.rb#1205 def parse_column_end; end # source://csv//lib/csv/parser.rb#1105 def parse_column_value; end # source://csv//lib/csv/parser.rb#792 def parse_headers(row); end # source://csv//lib/csv/parser.rb#945 def parse_no_quote(&block); end # source://csv//lib/csv/parser.rb#974 def parse_quotable_loose(&block); end # source://csv//lib/csv/parser.rb#1035 def parse_quotable_robust(&block); end # source://csv//lib/csv/parser.rb#1163 def parse_quoted_column_value; end # source://csv//lib/csv/parser.rb#1219 def parse_row_end; end # source://csv//lib/csv/parser.rb#1135 def parse_unquoted_column_value; end # A set of tasks to prepare the file in order to parse it # # source://csv//lib/csv/parser.rb#453 def prepare; end # source://csv//lib/csv/parser.rb#508 def prepare_backslash; end # source://csv//lib/csv/parser.rb#766 def prepare_header; end # source://csv//lib/csv/parser.rb#752 def prepare_line; end # source://csv//lib/csv/parser.rb#812 def prepare_parser; end # source://csv//lib/csv/parser.rb#492 def prepare_quote_character; end # source://csv//lib/csv/parser.rb#648 def prepare_quoted; end # source://csv//lib/csv/parser.rb#580 def prepare_separators; end # source://csv//lib/csv/parser.rb#523 def prepare_skip_lines; end # source://csv//lib/csv/parser.rb#540 def prepare_strip; end # source://csv//lib/csv/parser.rb#675 def prepare_unquoted; end # source://csv//lib/csv/parser.rb#468 def prepare_variable; end # source://csv//lib/csv/parser.rb#688 def resolve_row_separator(separator); end # @return [Boolean] # # source://csv//lib/csv/parser.rb#925 def skip_line?(line); end # source://csv//lib/csv/parser.rb#908 def skip_needless_lines; end # source://csv//lib/csv/parser.rb#1256 def start_row; end # source://csv//lib/csv/parser.rb#1232 def strip_value(value); end # @raise [MalformedCSVError] # # source://csv//lib/csv/parser.rb#937 def validate_field_size(field); end # This method verifies that there are no (obvious) ambiguities with the # provided +col_sep+ and +strip+ parsing options. For example, if +col_sep+ # and +strip+ were both equal to +\t+, then there would be no clear way to # parse the input. # # source://csv//lib/csv/parser.rb#630 def validate_strip_and_col_sep_options; end class << self # Convenient method to check whether the give input reached EOF # or not. # # @return [Boolean] # # source://csv//lib/csv/parser.rb#25 def eof?(input); end end end # CSV::InputsScanner receives IO inputs, encoding and the chunk_size. # It also controls the life cycle of the object with its methods +keep_start+, # +keep_end+, +keep_back+, +keep_drop+. # # CSV::InputsScanner.scan() tries to match with pattern at the current position. # If there's a match, the scanner advances the "scan pointer" and returns the matched string. # Otherwise, the scanner returns nil. # # CSV::InputsScanner.rest() returns the "rest" of the string (i.e. everything after the scan pointer). # If there is no more data (eos? = true), it returns "". # # source://csv//lib/csv/parser.rb#99 class CSV::Parser::InputsScanner # @return [InputsScanner] a new instance of InputsScanner # # source://csv//lib/csv/parser.rb#100 def initialize(inputs, encoding, row_separator, chunk_size: T.unsafe(nil)); end # source://csv//lib/csv/parser.rb#270 def check(pattern); end # @yield [buffer] # # source://csv//lib/csv/parser.rb#110 def each_line(row_separator); end # @return [Boolean] # # source://csv//lib/csv/parser.rb#183 def eos?; end # source://csv//lib/csv/parser.rb#210 def keep_back; end # source://csv//lib/csv/parser.rb#249 def keep_drop; end # source://csv//lib/csv/parser.rb#194 def keep_end; end # source://csv//lib/csv/parser.rb#187 def keep_start; end # source://csv//lib/csv/parser.rb#266 def rest; end # source://csv//lib/csv/parser.rb#156 def scan(pattern); end # source://csv//lib/csv/parser.rb#167 def scan_all(pattern); end private # source://csv//lib/csv/parser.rb#279 def adjust_last_keep; end # source://csv//lib/csv/parser.rb#307 def read_chunk; end # source://csv//lib/csv/parser.rb#275 def trace(*args); end end # Raised when encoding is invalid. # # source://csv//lib/csv/parser.rb#35 class CSV::Parser::InvalidEncoding < ::StandardError; end # source://csv//lib/csv/parser.rb#855 CSV::Parser::SCANNER_TEST = T.let(T.unsafe(nil), FalseClass) # source://csv//lib/csv/parser.rb#577 CSV::Parser::STRING_SCANNER_SCAN_ACCEPT_STRING = T.let(T.unsafe(nil), TrueClass) # CSV::Scanner receives a CSV output, scans it and return the content. # It also controls the life cycle of the object with its methods +keep_start+, # +keep_end+, +keep_back+, +keep_drop+. # # Uses StringScanner (the official strscan gem). Strscan provides lexical # scanning operations on a String. We inherit its object and take advantage # on the methods. For more information, please visit: # https://ruby-doc.org/stdlib-2.6.1/libdoc/strscan/rdoc/StringScanner.html # # source://csv//lib/csv/parser.rb#52 class CSV::Parser::Scanner < ::StringScanner # @return [Scanner] a new instance of Scanner # # source://csv//lib/csv/parser.rb#55 def initialize(*args); end # source://csv//lib/csv/parser.rb#60 def each_line(row_separator); end # source://csv//lib/csv/parser.rb#78 def keep_back; end # source://csv//lib/csv/parser.rb#82 def keep_drop; end # source://csv//lib/csv/parser.rb#73 def keep_end; end # source://csv//lib/csv/parser.rb#69 def keep_start; end def scan_all(_arg0); end end # Raised when unexpected case is happen. # # source://csv//lib/csv/parser.rb#39 class CSV::Parser::UnexpectedError < ::StandardError; end # source://csv//lib/csv/parser.rb#837 class CSV::Parser::UnoptimizedStringIO # @return [UnoptimizedStringIO] a new instance of UnoptimizedStringIO # # source://csv//lib/csv/parser.rb#838 def initialize(string); end # source://csv//lib/csv/parser.rb#846 def each_line(*args, &block); end # @return [Boolean] # # source://csv//lib/csv/parser.rb#850 def eof?; end # source://csv//lib/csv/parser.rb#842 def gets(*args); end end # = \CSV::Row # A \CSV::Row instance represents a \CSV table row. # (see {class CSV}[../CSV.html]). # # The instance may have: # - Fields: each is an object, not necessarily a \String. # - Headers: each serves a key, and also need not be a \String. # # === Instance Methods # # \CSV::Row has three groups of instance methods: # - Its own internally defined instance methods. # - Methods included by module Enumerable. # - Methods delegated to class Array.: # * Array#empty? # * Array#length # * Array#size # # == Creating a \CSV::Row Instance # # Commonly, a new \CSV::Row instance is created by parsing \CSV source # that has headers: # source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n" # table = CSV.parse(source, headers: true) # table.each {|row| p row } # Output: # # # # # # # # You can also create a row directly. See ::new. # # == Headers # # Like a \CSV::Table, a \CSV::Row has headers. # # A \CSV::Row that was created by parsing \CSV source # inherits its headers from the table: # source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n" # table = CSV.parse(source, headers: true) # row = table.first # row.headers # => ["Name", "Value"] # # You can also create a new row with headers; # like the keys in a \Hash, the headers need not be Strings: # row = CSV::Row.new([:name, :value], ['foo', 0]) # row.headers # => [:name, :value] # # The new row retains its headers even if added to a table # that has headers: # table << row # => # # row.headers # => [:name, :value] # row[:name] # => "foo" # row['Name'] # => nil # # # # == Accessing Fields # # You may access a field in a \CSV::Row with either its \Integer index # (\Array-style) or its header (\Hash-style). # # Fetch a field using method #[]: # row = CSV::Row.new(['Name', 'Value'], ['foo', 0]) # row[1] # => 0 # row['Value'] # => 0 # # Set a field using method #[]=: # row = CSV::Row.new(['Name', 'Value'], ['foo', 0]) # row # => # # row[0] = 'bar' # row['Value'] = 1 # row # => # # # source://csv//lib/csv/row.rb#80 class CSV::Row include ::Enumerable extend ::Forwardable # :call-seq: # CSV::Row.new(headers, fields, header_row = false) -> csv_row # # Returns the new \CSV::Row instance constructed from # arguments +headers+ and +fields+; both should be Arrays; # note that the fields need not be Strings: # row = CSV::Row.new(['Name', 'Value'], ['foo', 0]) # row # => # # # If the \Array lengths are different, the shorter is +nil+-filled: # row = CSV::Row.new(['Name', 'Value', 'Date', 'Size'], ['foo', 0]) # row # => # # # Each \CSV::Row object is either a field row or a header row; # by default, a new row is a field row; for the row created above: # row.field_row? # => true # row.header_row? # => false # # If the optional argument +header_row+ is given as +true+, # the created row is a header row: # row = CSV::Row.new(['Name', 'Value'], ['foo', 0], header_row = true) # row # => # # row.field_row? # => false # row.header_row? # => true # # @return [Row] a new instance of Row # # source://csv//lib/csv/row.rb#105 def initialize(headers, fields, header_row = T.unsafe(nil)); end # :call-seq: # row << [header, value] -> self # row << hash -> self # row << value -> self # # Adds a field to +self+; returns +self+: # # If the argument is a 2-element \Array [header, value], # a field is added with the given +header+ and +value+: # source = "Name,Name,Name\nFoo,Bar,Baz\n" # table = CSV.parse(source, headers: true) # row = table[0] # row << ['NAME', 'Bat'] # row # => # # # If the argument is a \Hash, each key-value pair is added # as a field with header +key+ and value +value+. # source = "Name,Name,Name\nFoo,Bar,Baz\n" # table = CSV.parse(source, headers: true) # row = table[0] # row << {NAME: 'Bat', name: 'Bam'} # row # => # # # Otherwise, the given +value+ is added as a field with no header. # source = "Name,Name,Name\nFoo,Bar,Baz\n" # table = CSV.parse(source, headers: true) # row = table[0] # row << 'Bag' # row # => # # # source://csv//lib/csv/row.rb#389 def <<(arg); end # :call-seq: # row == other -> true or false # # Returns +true+ if +other+ is a /CSV::Row that has the same # fields (headers and values) in the same order as +self+; # otherwise returns +false+: # source = "Name,Name,Name\nFoo,Bar,Baz\n" # table = CSV.parse(source, headers: true) # row = table[0] # other_row = table[0] # row == other_row # => true # other_row = table[1] # row == other_row # => false # # source://csv//lib/csv/row.rb#633 def ==(other); end # :call-seq: # field(index) -> value # field(header) -> value # field(header, offset) -> value # # Returns the field value for the given +index+ or +header+. # # --- # # Fetch field value by \Integer index: # source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n" # table = CSV.parse(source, headers: true) # row = table[0] # row.field(0) # => "foo" # row.field(1) # => "bar" # # Counts backward from the last column if +index+ is negative: # row.field(-1) # => "0" # row.field(-2) # => "foo" # # Returns +nil+ if +index+ is out of range: # row.field(2) # => nil # row.field(-3) # => nil # # --- # # Fetch field value by header (first found): # source = "Name,Name,Name\nFoo,Bar,Baz\n" # table = CSV.parse(source, headers: true) # row = table[0] # row.field('Name') # => "Foo" # # Fetch field value by header, ignoring +offset+ leading fields: # source = "Name,Name,Name\nFoo,Bar,Baz\n" # table = CSV.parse(source, headers: true) # row = table[0] # row.field('Name', 2) # => "Baz" # # Returns +nil+ if the header does not exist. # # source://csv//lib/csv/row.rb#203 def [](header_or_index, minimum_index = T.unsafe(nil)); end # :call-seq: # row[index] = value -> value # row[header, offset] = value -> value # row[header] = value -> value # # Assigns the field value for the given +index+ or +header+; # returns +value+. # # --- # # Assign field value by \Integer index: # source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n" # table = CSV.parse(source, headers: true) # row = table[0] # row[0] = 'Bat' # row[1] = 3 # row # => # # # Counts backward from the last column if +index+ is negative: # row[-1] = 4 # row[-2] = 'Bam' # row # => # # # Extends the row with nil:nil if positive +index+ is not in the row: # row[4] = 5 # row # => # # # Raises IndexError if negative +index+ is too small (too far from zero). # # --- # # Assign field value by header (first found): # source = "Name,Name,Name\nFoo,Bar,Baz\n" # table = CSV.parse(source, headers: true) # row = table[0] # row['Name'] = 'Bat' # row # => # # # Assign field value by header, ignoring +offset+ leading fields: # source = "Name,Name,Name\nFoo,Bar,Baz\n" # table = CSV.parse(source, headers: true) # row = table[0] # row['Name', 2] = 4 # row # => # # # Append new field by (new) header: # source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n" # table = CSV.parse(source, headers: true) # row = table[0] # row['New'] = 6 # row# => # # # source://csv//lib/csv/row.rb#339 def []=(*args); end # :call-seq: # row.deconstruct -> array # # Returns the new \Array suitable for pattern matching containing the values # of the row. # # source://csv//lib/csv/row.rb#682 def deconstruct; end # :call-seq: # row.deconstruct_keys(keys) -> hash # # Returns the new \Hash suitable for pattern matching containing only the # keys specified as an argument. # # source://csv//lib/csv/row.rb#667 def deconstruct_keys(keys); end # :call-seq: # delete(index) -> [header, value] or nil # delete(header) -> [header, value] or empty_array # delete(header, offset) -> [header, value] or empty_array # # Removes a specified field from +self+; returns the 2-element \Array # [header, value] if the field exists. # # If an \Integer argument +index+ is given, # removes and returns the field at offset +index+, # or returns +nil+ if the field does not exist: # source = "Name,Name,Name\nFoo,Bar,Baz\n" # table = CSV.parse(source, headers: true) # row = table[0] # row.delete(1) # => ["Name", "Bar"] # row.delete(50) # => nil # # Otherwise, if the single argument +header+ is given, # removes and returns the first-found field with the given header, # of returns a new empty \Array if the field does not exist: # source = "Name,Name,Name\nFoo,Bar,Baz\n" # table = CSV.parse(source, headers: true) # row = table[0] # row.delete('Name') # => ["Name", "Foo"] # row.delete('NAME') # => [] # # If argument +header+ and \Integer argument +offset+ are given, # removes and returns the first-found field with the given header # whose +index+ is at least as large as +offset+: # source = "Name,Name,Name\nFoo,Bar,Baz\n" # table = CSV.parse(source, headers: true) # row = table[0] # row.delete('Name', 1) # => ["Name", "Bar"] # row.delete('NAME', 1) # => [] # # source://csv//lib/csv/row.rb#451 def delete(header_or_index, minimum_index = T.unsafe(nil)); end # :call-seq: # row.delete_if {|header, value| ... } -> self # # Removes fields from +self+ as selected by the block; returns +self+. # # Removes each field for which the block returns a truthy value: # source = "Name,Name,Name\nFoo,Bar,Baz\n" # table = CSV.parse(source, headers: true) # row = table[0] # row.delete_if {|header, value| value.start_with?('B') } # => true # row # => # # row.delete_if {|header, value| header.start_with?('B') } # => false # # If no block is given, returns a new Enumerator: # row.delete_if # => #:delete_if> # # source://csv//lib/csv/row.rb#476 def delete_if(&block); end # :call-seq: # row.dig(index_or_header, *identifiers) -> object # # Finds and returns the object in nested object that is specified # by +index_or_header+ and +specifiers+. # # The nested objects may be instances of various classes. # See {Dig Methods}[rdoc-ref:dig_methods.rdoc]. # # Examples: # source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n" # table = CSV.parse(source, headers: true) # row = table[0] # row.dig(1) # => "0" # row.dig('Value') # => "0" # row.dig(5) # => nil # # source://csv//lib/csv/row.rb#715 def dig(index_or_header, *indexes); end # :call-seq: # row.each {|header, value| ... } -> self # # Calls the block with each header-value pair; returns +self+: # source = "Name,Name,Name\nFoo,Bar,Baz\n" # table = CSV.parse(source, headers: true) # row = table[0] # row.each {|header, value| p [header, value] } # Output: # ["Name", "Foo"] # ["Name", "Bar"] # ["Name", "Baz"] # # If no block is given, returns a new Enumerator: # row.each # => #:each> # # source://csv//lib/csv/row.rb#610 def each(&block); end # :call-seq: # row.each {|header, value| ... } -> self # # Calls the block with each header-value pair; returns +self+: # source = "Name,Name,Name\nFoo,Bar,Baz\n" # table = CSV.parse(source, headers: true) # row = table[0] # row.each {|header, value| p [header, value] } # Output: # ["Name", "Foo"] # ["Name", "Bar"] # ["Name", "Baz"] # # If no block is given, returns a new Enumerator: # row.each # => #:each> # # source://csv//lib/csv/row.rb#610 def each_pair(&block); end # :call-seq: # fetch(header) -> value # fetch(header, default) -> value # fetch(header) {|row| ... } -> value # # Returns the field value as specified by +header+. # # --- # # With the single argument +header+, returns the field value # for that header (first found): # source = "Name,Name,Name\nFoo,Bar,Baz\n" # table = CSV.parse(source, headers: true) # row = table[0] # row.fetch('Name') # => "Foo" # # Raises exception +KeyError+ if the header does not exist. # # --- # # With arguments +header+ and +default+ given, # returns the field value for the header (first found) # if the header exists, otherwise returns +default+: # source = "Name,Name,Name\nFoo,Bar,Baz\n" # table = CSV.parse(source, headers: true) # row = table[0] # row.fetch('Name', '') # => "Foo" # row.fetch(:nosuch, '') # => "" # # --- # # With argument +header+ and a block given, # returns the field value for the header (first found) # if the header exists; otherwise calls the block # and returns its return value: # source = "Name,Name,Name\nFoo,Bar,Baz\n" # table = CSV.parse(source, headers: true) # row = table[0] # row.fetch('Name') {|header| fail 'Cannot happen' } # => "Foo" # row.fetch(:nosuch) {|header| "Header '#{header} not found'" } # => "Header 'nosuch not found'" # # @raise [ArgumentError] # # source://csv//lib/csv/row.rb#258 def fetch(header, *varargs); end # :call-seq: # field(index) -> value # field(header) -> value # field(header, offset) -> value # # Returns the field value for the given +index+ or +header+. # # --- # # Fetch field value by \Integer index: # source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n" # table = CSV.parse(source, headers: true) # row = table[0] # row.field(0) # => "foo" # row.field(1) # => "bar" # # Counts backward from the last column if +index+ is negative: # row.field(-1) # => "0" # row.field(-2) # => "foo" # # Returns +nil+ if +index+ is out of range: # row.field(2) # => nil # row.field(-3) # => nil # # --- # # Fetch field value by header (first found): # source = "Name,Name,Name\nFoo,Bar,Baz\n" # table = CSV.parse(source, headers: true) # row = table[0] # row.field('Name') # => "Foo" # # Fetch field value by header, ignoring +offset+ leading fields: # source = "Name,Name,Name\nFoo,Bar,Baz\n" # table = CSV.parse(source, headers: true) # row = table[0] # row.field('Name', 2) # => "Baz" # # Returns +nil+ if the header does not exist. # # source://csv//lib/csv/row.rb#203 def field(header_or_index, minimum_index = T.unsafe(nil)); end # :call-seq: # row.field?(value) -> true or false # # Returns +true+ if +value+ is a field in this row, +false+ otherwise: # source = "Name,Name,Name\nFoo,Bar,Baz\n" # table = CSV.parse(source, headers: true) # row = table[0] # row.field?('Bar') # => true # row.field?('BAR') # => false # # @return [Boolean] # # source://csv//lib/csv/row.rb#589 def field?(data); end # :call-seq: # row.field_row? -> true or false # # Returns +true+ if this is a field row, +false+ otherwise. # # @return [Boolean] # # source://csv//lib/csv/row.rb#148 def field_row?; end # :call-seq: # self.fields(*specifiers) -> array_of_fields # # Returns field values per the given +specifiers+, which may be any mixture of: # - \Integer index. # - \Range of \Integer indexes. # - 2-element \Array containing a header and offset. # - Header. # - \Range of headers. # # For +specifier+ in one of the first four cases above, # returns the result of self.field(specifier); see #field. # # Although there may be any number of +specifiers+, # the examples here will illustrate one at a time. # # When the specifier is an \Integer +index+, # returns self.field(index)L # source = "Name,Name,Name\nFoo,Bar,Baz\n" # table = CSV.parse(source, headers: true) # row = table[0] # row.fields(1) # => ["Bar"] # # When the specifier is a \Range of \Integers +range+, # returns self.field(range): # row.fields(1..2) # => ["Bar", "Baz"] # # When the specifier is a 2-element \Array +array+, # returns self.field(array)L # row.fields('Name', 1) # => ["Foo", "Bar"] # # When the specifier is a header +header+, # returns self.field(header)L # row.fields('Name') # => ["Foo"] # # When the specifier is a \Range of headers +range+, # forms a new \Range +new_range+ from the indexes of # range.start and range.end, # and returns self.field(new_range): # source = "Name,NAME,name\nFoo,Bar,Baz\n" # table = CSV.parse(source, headers: true) # row = table[0] # row.fields('Name'..'NAME') # => ["Foo", "Bar"] # # Returns all fields if no argument given: # row.fields # => ["Foo", "Bar", "Baz"] # # source://csv//lib/csv/row.rb#530 def fields(*headers_and_or_indices); end # :call-seq: # row.has_key?(header) -> true or false # # Returns +true+ if there is a field with the given +header+, # +false+ otherwise. # # @return [Boolean] # # source://csv//lib/csv/row.rb#279 def has_key?(header); end # :call-seq: # row.has_key?(header) -> true or false # # Returns +true+ if there is a field with the given +header+, # +false+ otherwise. # # @return [Boolean] # # source://csv//lib/csv/row.rb#279 def header?(header); end # :call-seq: # row.header_row? -> true or false # # Returns +true+ if this is a header row, +false+ otherwise. # # @return [Boolean] # # source://csv//lib/csv/row.rb#140 def header_row?; end # :call-seq: # row.headers -> array_of_headers # # Returns the headers for this row: # source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n" # table = CSV.parse(source, headers: true) # row = table.first # row.headers # => ["Name", "Value"] # # source://csv//lib/csv/row.rb#160 def headers; end # :call-seq: # row.has_key?(header) -> true or false # # Returns +true+ if there is a field with the given +header+, # +false+ otherwise. # # @return [Boolean] # # source://csv//lib/csv/row.rb#279 def include?(header); end # :call-seq: # index(header) -> index # index(header, offset) -> index # # Returns the index for the given header, if it exists; # otherwise returns +nil+. # # With the single argument +header+, returns the index # of the first-found field with the given +header+: # source = "Name,Name,Name\nFoo,Bar,Baz\n" # table = CSV.parse(source, headers: true) # row = table[0] # row.index('Name') # => 0 # row.index('NAME') # => nil # # With arguments +header+ and +offset+, # returns the index of the first-found field with given +header+, # but ignoring the first +offset+ fields: # row.index('Name', 1) # => 1 # row.index('Name', 3) # => nil # # source://csv//lib/csv/row.rb#573 def index(header, minimum_index = T.unsafe(nil)); end # :call-seq: # row.inspect -> string # # Returns an ASCII-compatible \String showing: # - Class \CSV::Row. # - Header-value pairs. # Example: # source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n" # table = CSV.parse(source, headers: true) # row = table[0] # row.inspect # => "#" # # source://csv//lib/csv/row.rb#740 def inspect; end # :call-seq: # row.has_key?(header) -> true or false # # Returns +true+ if there is a field with the given +header+, # +false+ otherwise. # # @return [Boolean] # # source://csv//lib/csv/row.rb#279 def key?(header); end # :call-seq: # row.has_key?(header) -> true or false # # Returns +true+ if there is a field with the given +header+, # +false+ otherwise. # # @return [Boolean] # # source://csv//lib/csv/row.rb#279 def member?(header); end # :call-seq: # row.push(*values) -> self # # Appends each of the given +values+ to +self+ as a field; returns +self+: # source = "Name,Name,Name\nFoo,Bar,Baz\n" # table = CSV.parse(source, headers: true) # row = table[0] # row.push('Bat', 'Bam') # row # => # # # source://csv//lib/csv/row.rb#410 def push(*args); end # :call-seq: # row.to_csv -> csv_string # # Returns the row as a \CSV String. Headers are not included: # source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n" # table = CSV.parse(source, headers: true) # row = table[0] # row.to_csv # => "foo,0\n" # # source://csv//lib/csv/row.rb#694 def to_csv(**options); end # :call-seq: # row.to_h -> hash # # Returns the new \Hash formed by adding each header-value pair in +self+ # as a key-value pair in the \Hash. # source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n" # table = CSV.parse(source, headers: true) # row = table[0] # row.to_h # => {"Name"=>"foo", "Value"=>"0"} # # Header order is preserved, but repeated headers are ignored: # source = "Name,Name,Name\nFoo,Bar,Baz\n" # table = CSV.parse(source, headers: true) # row = table[0] # row.to_h # => {"Name"=>"Foo"} # # source://csv//lib/csv/row.rb#653 def to_h; end # :call-seq: # row.to_h -> hash # # Returns the new \Hash formed by adding each header-value pair in +self+ # as a key-value pair in the \Hash. # source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n" # table = CSV.parse(source, headers: true) # row = table[0] # row.to_h # => {"Name"=>"foo", "Value"=>"0"} # # Header order is preserved, but repeated headers are ignored: # source = "Name,Name,Name\nFoo,Bar,Baz\n" # table = CSV.parse(source, headers: true) # row = table[0] # row.to_h # => {"Name"=>"Foo"} # # source://csv//lib/csv/row.rb#653 def to_hash; end # :call-seq: # row.to_csv -> csv_string # # Returns the row as a \CSV String. Headers are not included: # source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n" # table = CSV.parse(source, headers: true) # row = table[0] # row.to_csv # => "foo,0\n" # # source://csv//lib/csv/row.rb#694 def to_s(**options); end # :call-seq: # self.fields(*specifiers) -> array_of_fields # # Returns field values per the given +specifiers+, which may be any mixture of: # - \Integer index. # - \Range of \Integer indexes. # - 2-element \Array containing a header and offset. # - Header. # - \Range of headers. # # For +specifier+ in one of the first four cases above, # returns the result of self.field(specifier); see #field. # # Although there may be any number of +specifiers+, # the examples here will illustrate one at a time. # # When the specifier is an \Integer +index+, # returns self.field(index)L # source = "Name,Name,Name\nFoo,Bar,Baz\n" # table = CSV.parse(source, headers: true) # row = table[0] # row.fields(1) # => ["Bar"] # # When the specifier is a \Range of \Integers +range+, # returns self.field(range): # row.fields(1..2) # => ["Bar", "Baz"] # # When the specifier is a 2-element \Array +array+, # returns self.field(array)L # row.fields('Name', 1) # => ["Foo", "Bar"] # # When the specifier is a header +header+, # returns self.field(header)L # row.fields('Name') # => ["Foo"] # # When the specifier is a \Range of headers +range+, # forms a new \Range +new_range+ from the indexes of # range.start and range.end, # and returns self.field(new_range): # source = "Name,NAME,name\nFoo,Bar,Baz\n" # table = CSV.parse(source, headers: true) # row = table[0] # row.fields('Name'..'NAME') # => ["Foo", "Bar"] # # Returns all fields if no argument given: # row.fields # => ["Foo", "Bar", "Baz"] # # source://csv//lib/csv/row.rb#530 def values_at(*headers_and_or_indices); end protected # Internal data format used to compare equality. # # source://csv//lib/csv/row.rb#118 def row; end private # :call-seq: # row.initialize_copy(other_row) -> self # # Calls superclass method. # # source://csv//lib/csv/row.rb#130 def initialize_copy(other); end end # source://csv//lib/csv.rb#2132 class CSV::TSV < ::CSV # @return [TSV] a new instance of TSV # # source://csv//lib/csv.rb#2133 def initialize(data, **options); end end # = \CSV::Table # A \CSV::Table instance represents \CSV data. # (see {class CSV}[../CSV.html]). # # The instance may have: # - Rows: each is a Table::Row object. # - Headers: names for the columns. # # === Instance Methods # # \CSV::Table has three groups of instance methods: # - Its own internally defined instance methods. # - Methods included by module Enumerable. # - Methods delegated to class Array.: # * Array#empty? # * Array#length # * Array#size # # == Creating a \CSV::Table Instance # # Commonly, a new \CSV::Table instance is created by parsing \CSV source # using headers: # source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n" # table = CSV.parse(source, headers: true) # table.class # => CSV::Table # # You can also create an instance directly. See ::new. # # == Headers # # If a table has headers, the headers serve as labels for the columns of data. # Each header serves as the label for its column. # # The headers for a \CSV::Table object are stored as an \Array of Strings. # # Commonly, headers are defined in the first row of \CSV source: # source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n" # table = CSV.parse(source, headers: true) # table.headers # => ["Name", "Value"] # # If no headers are defined, the \Array is empty: # table = CSV::Table.new([]) # table.headers # => [] # # == Access Modes # # \CSV::Table provides three modes for accessing table data: # - \Row mode. # - Column mode. # - Mixed mode (the default for a new table). # # The access mode for a\CSV::Table instance affects the behavior # of some of its instance methods: # - #[] # - #[]= # - #delete # - #delete_if # - #each # - #values_at # # === \Row Mode # # Set a table to row mode with method #by_row!: # source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n" # table = CSV.parse(source, headers: true) # table.by_row! # => # # # Specify a single row by an \Integer index: # # Get a row. # table[1] # => # # # Set a row, then get it. # table[1] = CSV::Row.new(['Name', 'Value'], ['bam', 3]) # table[1] # => # # # Specify a sequence of rows by a \Range: # # Get rows. # table[1..2] # => [#, #] # # Set rows, then get them. # table[1..2] = [ # CSV::Row.new(['Name', 'Value'], ['bat', 4]), # CSV::Row.new(['Name', 'Value'], ['bad', 5]), # ] # table[1..2] # => [["Name", #], ["Value", #]] # # === Column Mode # # Set a table to column mode with method #by_col!: # source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n" # table = CSV.parse(source, headers: true) # table.by_col! # => # # # Specify a column by an \Integer index: # # Get a column. # table[0] # # Set a column, then get it. # table[0] = ['FOO', 'BAR', 'BAZ'] # table[0] # => ["FOO", "BAR", "BAZ"] # # Specify a column by its \String header: # # Get a column. # table['Name'] # => ["FOO", "BAR", "BAZ"] # # Set a column, then get it. # table['Name'] = ['Foo', 'Bar', 'Baz'] # table['Name'] # => ["Foo", "Bar", "Baz"] # # === Mixed Mode # # In mixed mode, you can refer to either rows or columns: # - An \Integer index refers to a row. # - A \Range index refers to multiple rows. # - A \String index refers to a column. # # Set a table to mixed mode with method #by_col_or_row!: # source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n" # table = CSV.parse(source, headers: true) # table.by_col_or_row! # => # # # Specify a single row by an \Integer index: # # Get a row. # table[1] # => # # # Set a row, then get it. # table[1] = CSV::Row.new(['Name', 'Value'], ['bam', 3]) # table[1] # => # # # Specify a sequence of rows by a \Range: # # Get rows. # table[1..2] # => [#, #] # # Set rows, then get them. # table[1] = CSV::Row.new(['Name', 'Value'], ['bat', 4]) # table[2] = CSV::Row.new(['Name', 'Value'], ['bad', 5]) # table[1..2] # => [["Name", #], ["Value", #]] # # Specify a column by its \String header: # # Get a column. # table['Name'] # => ["foo", "bat", "bad"] # # Set a column, then get it. # table['Name'] = ['Foo', 'Bar', 'Baz'] # table['Name'] # => ["Foo", "Bar", "Baz"] # # source://csv//lib/csv/table.rb#144 class CSV::Table include ::Enumerable extend ::Forwardable # :call-seq: # CSV::Table.new(array_of_rows, headers = nil) -> csv_table # # Returns a new \CSV::Table object. # # - Argument +array_of_rows+ must be an \Array of CSV::Row objects. # - Argument +headers+, if given, may be an \Array of Strings. # # --- # # Create an empty \CSV::Table object: # table = CSV::Table.new([]) # table # => # # # Create a non-empty \CSV::Table object: # rows = [ # CSV::Row.new([], []), # CSV::Row.new([], []), # CSV::Row.new([], []), # ] # table = CSV::Table.new(rows) # table # => # # # --- # # If argument +headers+ is an \Array of Strings, # those Strings become the table's headers: # table = CSV::Table.new([], headers: ['Name', 'Age']) # table.headers # => ["Name", "Age"] # # If argument +headers+ is not given and the table has rows, # the headers are taken from the first row: # rows = [ # CSV::Row.new(['Foo', 'Bar'], []), # CSV::Row.new(['foo', 'bar'], []), # CSV::Row.new(['FOO', 'BAR'], []), # ] # table = CSV::Table.new(rows) # table.headers # => ["Foo", "Bar"] # # If argument +headers+ is not given and the table is empty (has no rows), # the headers are also empty: # table = CSV::Table.new([]) # table.headers # => [] # # --- # # Raises an exception if argument +array_of_rows+ is not an \Array object: # # Raises NoMethodError (undefined method `first' for :foo:Symbol): # CSV::Table.new(:foo) # # Raises an exception if an element of +array_of_rows+ is not a \CSV::Table object: # # Raises NoMethodError (undefined method `headers' for :foo:Symbol): # CSV::Table.new([:foo]) # # @return [Table] a new instance of Table # # source://csv//lib/csv/table.rb#199 def initialize(array_of_rows, headers: T.unsafe(nil)); end # :call-seq: # table << row_or_array -> self # # If +row_or_array+ is a \CSV::Row object, # it is appended to the table: # source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n" # table = CSV.parse(source, headers: true) # table << CSV::Row.new(table.headers, ['bat', 3]) # table[3] # => # # # If +row_or_array+ is an \Array, it is used to create a new # \CSV::Row object which is then appended to the table: # table << ['bam', 4] # table[4] # => # # # source://csv//lib/csv/table.rb#762 def <<(row_or_array); end # :call-seq: # table == other_table -> true or false # # Returns +true+ if all each row of +self+ == # the corresponding row of +other_table+, otherwise, +false+. # # The access mode does no affect the result. # # Equal tables: # source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n" # table = CSV.parse(source, headers: true) # other_table = CSV.parse(source, headers: true) # table == other_table # => true # # Different row count: # other_table.delete(2) # table == other_table # => false # # Different last row: # other_table << ['bat', 3] # table == other_table # => false # # source://csv//lib/csv/table.rb#965 def ==(other); end # :call-seq: # table[n] -> row or column_data # table[range] -> array_of_rows or array_of_column_data # table[header] -> array_of_column_data # # Returns data from the table; does not modify the table. # # --- # # Fetch a \Row by Its \Integer Index:: # - Form: table[n], +n+ an integer. # - Access mode: :row or :col_or_row. # - Return value: _nth_ row of the table, if that row exists; # otherwise +nil+. # # Returns the _nth_ row of the table if that row exists: # source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n" # table = CSV.parse(source, headers: true) # table.by_row! # => # # table[1] # => # # table.by_col_or_row! # => # # table[1] # => # # # Counts backward from the last row if +n+ is negative: # table[-1] # => # # # Returns +nil+ if +n+ is too large or too small: # table[4] # => nil # table[-4] # => nil # # Raises an exception if the access mode is :row # and +n+ is not an \Integer: # table.by_row! # => # # # Raises TypeError (no implicit conversion of String into Integer): # table['Name'] # # --- # # Fetch a Column by Its \Integer Index:: # - Form: table[n], +n+ an \Integer. # - Access mode: :col. # - Return value: _nth_ column of the table, if that column exists; # otherwise an \Array of +nil+ fields of length self.size. # # Returns the _nth_ column of the table if that column exists: # source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n" # table = CSV.parse(source, headers: true) # table.by_col! # => # # table[1] # => ["0", "1", "2"] # # Counts backward from the last column if +n+ is negative: # table[-2] # => ["foo", "bar", "baz"] # # Returns an \Array of +nil+ fields if +n+ is too large or too small: # table[4] # => [nil, nil, nil] # table[-4] # => [nil, nil, nil] # # --- # # Fetch Rows by \Range:: # - Form: table[range], +range+ a \Range object. # - Access mode: :row or :col_or_row. # - Return value: rows from the table, beginning at row range.start, # if those rows exists. # # Returns rows from the table, beginning at row range.first, # if those rows exist: # source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n" # table = CSV.parse(source, headers: true) # table.by_row! # => # # rows = table[1..2] # => # # rows # => [#, #] # table.by_col_or_row! # => # # rows = table[1..2] # => # # rows # => [#, #] # # If there are too few rows, returns all from range.start to the end: # rows = table[1..50] # => # # rows # => [#, #] # # Special case: if range.start == table.size, returns an empty \Array: # table[table.size..50] # => [] # # If range.end is negative, calculates the ending index from the end: # rows = table[0..-1] # rows # => [#, #, #] # # If range.start is negative, calculates the starting index from the end: # rows = table[-1..2] # rows # => [#] # # If range.start is larger than table.size, returns +nil+: # table[4..4] # => nil # # --- # # Fetch Columns by \Range:: # - Form: table[range], +range+ a \Range object. # - Access mode: :col. # - Return value: column data from the table, beginning at column range.start, # if those columns exist. # # Returns column values from the table, if the column exists; # the values are arranged by row: # source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n" # table = CSV.parse(source, headers: true) # table.by_col! # table[0..1] # => [["foo", "0"], ["bar", "1"], ["baz", "2"]] # # Special case: if range.start == headers.size, # returns an \Array (size: table.size) of empty \Arrays: # table[table.headers.size..50] # => [[], [], []] # # If range.end is negative, calculates the ending index from the end: # table[0..-1] # => [["foo", "0"], ["bar", "1"], ["baz", "2"]] # # If range.start is negative, calculates the starting index from the end: # table[-2..2] # => [["foo", "0"], ["bar", "1"], ["baz", "2"]] # # If range.start is larger than table.size, # returns an \Array of +nil+ values: # table[4..4] # => [nil, nil, nil] # # --- # # Fetch a Column by Its \String Header:: # - Form: table[header], +header+ a \String header. # - Access mode: :col or :col_or_row # - Return value: column data from the table, if that +header+ exists. # # Returns column values from the table, if the column exists: # source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n" # table = CSV.parse(source, headers: true) # table.by_col! # => # # table['Name'] # => ["foo", "bar", "baz"] # table.by_col_or_row! # => # # col = table['Name'] # col # => ["foo", "bar", "baz"] # # Modifying the returned column values does not modify the table: # col[0] = 'bat' # col # => ["bat", "bar", "baz"] # table['Name'] # => ["foo", "bar", "baz"] # # Returns an \Array of +nil+ values if there is no such column: # table['Nosuch'] # => [nil, nil, nil] # # source://csv//lib/csv/table.rb#514 def [](index_or_header); end # :call-seq: # table[n] = row -> row # table[n] = field_or_array_of_fields -> field_or_array_of_fields # table[header] = field_or_array_of_fields -> field_or_array_of_fields # # Puts data onto the table. # # --- # # Set a \Row by Its \Integer Index:: # - Form: table[n] = row, +n+ an \Integer, # +row+ a \CSV::Row instance or an \Array of fields. # - Access mode: :row or :col_or_row. # - Return value: +row+. # # If the row exists, it is replaced: # source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n" # table = CSV.parse(source, headers: true) # new_row = CSV::Row.new(['Name', 'Value'], ['bat', 3]) # table.by_row! # => # # return_value = table[0] = new_row # return_value.equal?(new_row) # => true # Returned the row # table[0].to_h # => {"Name"=>"bat", "Value"=>3} # # With access mode :col_or_row: # table.by_col_or_row! # => # # table[0] = CSV::Row.new(['Name', 'Value'], ['bam', 4]) # table[0].to_h # => {"Name"=>"bam", "Value"=>4} # # With an \Array instead of a \CSV::Row, inherits headers from the table: # array = ['bad', 5] # return_value = table[0] = array # return_value.equal?(array) # => true # Returned the array # table[0].to_h # => {"Name"=>"bad", "Value"=>5} # # If the row does not exist, extends the table by adding rows: # assigns rows with +nil+ as needed: # table.size # => 3 # table[5] = ['bag', 6] # table.size # => 6 # table[3] # => nil # table[4]# => nil # table[5].to_h # => {"Name"=>"bag", "Value"=>6} # # Note that the +nil+ rows are actually +nil+, not a row of +nil+ fields. # # --- # # Set a Column by Its \Integer Index:: # - Form: table[n] = array_of_fields, +n+ an \Integer, # +array_of_fields+ an \Array of \String fields. # - Access mode: :col. # - Return value: +array_of_fields+. # # If the column exists, it is replaced: # source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n" # table = CSV.parse(source, headers: true) # new_col = [3, 4, 5] # table.by_col! # => # # return_value = table[1] = new_col # return_value.equal?(new_col) # => true # Returned the column # table[1] # => [3, 4, 5] # # The rows, as revised: # table.by_row! # => # # table[0].to_h # => {"Name"=>"foo", "Value"=>3} # table[1].to_h # => {"Name"=>"bar", "Value"=>4} # table[2].to_h # => {"Name"=>"baz", "Value"=>5} # table.by_col! # => # # # If there are too few values, fills with +nil+ values: # table[1] = [0] # table[1] # => [0, nil, nil] # # If there are too many values, ignores the extra values: # table[1] = [0, 1, 2, 3, 4] # table[1] # => [0, 1, 2] # # If a single value is given, replaces all fields in the column with that value: # table[1] = 'bat' # table[1] # => ["bat", "bat", "bat"] # # --- # # Set a Column by Its \String Header:: # - Form: table[header] = field_or_array_of_fields, # +header+ a \String header, +field_or_array_of_fields+ a field value # or an \Array of \String fields. # - Access mode: :col or :col_or_row. # - Return value: +field_or_array_of_fields+. # # If the column exists, it is replaced: # source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n" # table = CSV.parse(source, headers: true) # new_col = [3, 4, 5] # table.by_col! # => # # return_value = table['Value'] = new_col # return_value.equal?(new_col) # => true # Returned the column # table['Value'] # => [3, 4, 5] # # The rows, as revised: # table.by_row! # => # # table[0].to_h # => {"Name"=>"foo", "Value"=>3} # table[1].to_h # => {"Name"=>"bar", "Value"=>4} # table[2].to_h # => {"Name"=>"baz", "Value"=>5} # table.by_col! # => # # # If there are too few values, fills with +nil+ values: # table['Value'] = [0] # table['Value'] # => [0, nil, nil] # # If there are too many values, ignores the extra values: # table['Value'] = [0, 1, 2, 3, 4] # table['Value'] # => [0, 1, 2] # # If the column does not exist, extends the table by adding columns: # table['Note'] = ['x', 'y', 'z'] # table['Note'] # => ["x", "y", "z"] # # The rows, as revised: # table.by_row! # table[0].to_h # => {"Name"=>"foo", "Value"=>0, "Note"=>"x"} # table[1].to_h # => {"Name"=>"bar", "Value"=>1, "Note"=>"y"} # table[2].to_h # => {"Name"=>"baz", "Value"=>2, "Note"=>"z"} # table.by_col! # # If a single value is given, replaces all fields in the column with that value: # table['Value'] = 'bat' # table['Value'] # => ["bat", "bat", "bat"] # # source://csv//lib/csv/table.rb#649 def []=(index_or_header, value); end # :call-seq: # table.by_col -> table_dup # # Returns a duplicate of +self+, in column mode # (see {Column Mode}[#class-CSV::Table-label-Column+Mode]): # source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n" # table = CSV.parse(source, headers: true) # table.mode # => :col_or_row # dup_table = table.by_col # dup_table.mode # => :col # dup_table.equal?(table) # => false # It's a dup # # This may be used to chain method calls without changing the mode # (but also will affect performance and memory usage): # dup_table.by_col['Name'] # # Also note that changes to the duplicate table will not affect the original. # # source://csv//lib/csv/table.rb#242 def by_col; end # :call-seq: # table.by_col! -> self # # Sets the mode for +self+ to column mode # (see {Column Mode}[#class-CSV::Table-label-Column+Mode]); returns +self+: # source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n" # table = CSV.parse(source, headers: true) # table.mode # => :col_or_row # table1 = table.by_col! # table.mode # => :col # table1.equal?(table) # => true # Returned self # # source://csv//lib/csv/table.rb#257 def by_col!; end # :call-seq: # table.by_col_or_row -> table_dup # # Returns a duplicate of +self+, in mixed mode # (see {Mixed Mode}[#class-CSV::Table-label-Mixed+Mode]): # source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n" # table = CSV.parse(source, headers: true).by_col! # table.mode # => :col # dup_table = table.by_col_or_row # dup_table.mode # => :col_or_row # dup_table.equal?(table) # => false # It's a dup # # This may be used to chain method calls without changing the mode # (but also will affect performance and memory usage): # dup_table.by_col_or_row['Name'] # # Also note that changes to the duplicate table will not affect the original. # # source://csv//lib/csv/table.rb#280 def by_col_or_row; end # :call-seq: # table.by_col_or_row! -> self # # Sets the mode for +self+ to mixed mode # (see {Mixed Mode}[#class-CSV::Table-label-Mixed+Mode]); returns +self+: # source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n" # table = CSV.parse(source, headers: true).by_col! # table.mode # => :col # table1 = table.by_col_or_row! # table.mode # => :col_or_row # table1.equal?(table) # => true # Returned self # # source://csv//lib/csv/table.rb#295 def by_col_or_row!; end # :call-seq: # table.by_row -> table_dup # # Returns a duplicate of +self+, in row mode # (see {Row Mode}[#class-CSV::Table-label-Row+Mode]): # source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n" # table = CSV.parse(source, headers: true) # table.mode # => :col_or_row # dup_table = table.by_row # dup_table.mode # => :row # dup_table.equal?(table) # => false # It's a dup # # This may be used to chain method calls without changing the mode # (but also will affect performance and memory usage): # dup_table.by_row[1] # # Also note that changes to the duplicate table will not affect the original. # # source://csv//lib/csv/table.rb#318 def by_row; end # :call-seq: # table.by_row! -> self # # Sets the mode for +self+ to row mode # (see {Row Mode}[#class-CSV::Table-label-Row+Mode]); returns +self+: # source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n" # table = CSV.parse(source, headers: true) # table.mode # => :col_or_row # table1 = table.by_row! # table.mode # => :row # table1.equal?(table) # => true # Returned self # # source://csv//lib/csv/table.rb#333 def by_row!; end # :call-seq: # table.delete(*indexes) -> deleted_values # table.delete(*headers) -> deleted_values # # If the access mode is :row or :col_or_row, # and each argument is either an \Integer or a \Range, # returns deleted rows. # Otherwise, returns deleted columns data. # # In either case, the returned values are in the order # specified by the arguments. Arguments may be repeated. # # --- # # Returns rows as an \Array of \CSV::Row objects. # # One index: # source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n" # table = CSV.parse(source, headers: true) # deleted_values = table.delete(0) # deleted_values # => [#] # # Two indexes: # table = CSV.parse(source, headers: true) # deleted_values = table.delete(2, 0) # deleted_values # => [#, #] # # --- # # Returns columns data as column Arrays. # # One header: # table = CSV.parse(source, headers: true) # deleted_values = table.delete('Name') # deleted_values # => ["foo", "bar", "baz"] # # Two headers: # table = CSV.parse(source, headers: true) # deleted_values = table.delete('Value', 'Name') # deleted_values # => [["0", "1", "2"], ["foo", "bar", "baz"]] # # source://csv//lib/csv/table.rb#834 def delete(*indexes_or_headers); end # :call-seq: # table.delete_if {|row_or_column| ... } -> self # # Removes rows or columns for which the block returns a truthy value; # returns +self+. # # Removes rows when the access mode is :row or :col_or_row; # calls the block with each \CSV::Row object: # source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n" # table = CSV.parse(source, headers: true) # table.by_row! # => # # table.size # => 3 # table.delete_if {|row| row['Name'].start_with?('b') } # table.size # => 1 # # Removes columns when the access mode is :col; # calls the block with each column as a 2-element array # containing the header and an \Array of column fields: # source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n" # table = CSV.parse(source, headers: true) # table.by_col! # => # # table.headers.size # => 2 # table.delete_if {|column_data| column_data[1].include?('2') } # table.headers.size # => 1 # # Returns a new \Enumerator if no block is given: # source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n" # table = CSV.parse(source, headers: true) # table.delete_if # => #:delete_if> # # source://csv//lib/csv/table.rb#887 def delete_if(&block); end # Extracts the nested value specified by the sequence of +index+ or +header+ objects by calling dig at each step, # returning nil if any intermediate step is nil. # # source://csv//lib/csv/table.rb#1021 def dig(index_or_header, *index_or_headers); end # :call-seq: # table.each {|row_or_column| ... ) -> self # # Calls the block with each row or column; returns +self+. # # When the access mode is :row or :col_or_row, # calls the block with each \CSV::Row object: # source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n" # table = CSV.parse(source, headers: true) # table.by_row! # => # # table.each {|row| p row } # Output: # # # # # # # # When the access mode is :col, # calls the block with each column as a 2-element array # containing the header and an \Array of column fields: # table.by_col! # => # # table.each {|column_data| p column_data } # Output: # ["Name", ["foo", "bar", "baz"]] # ["Value", ["0", "1", "2"]] # # Returns a new \Enumerator if no block is given: # table.each # => #:each> # # source://csv//lib/csv/table.rb#930 def each(&block); end # :call-seq: # table.headers -> array_of_headers # # Returns a new \Array containing the \String headers for the table. # # If the table is not empty, returns the headers from the first row: # rows = [ # CSV::Row.new(['Foo', 'Bar'], []), # CSV::Row.new(['FOO', 'BAR'], []), # CSV::Row.new(['foo', 'bar'], []), # ] # table = CSV::Table.new(rows) # table.headers # => ["Foo", "Bar"] # table.delete(0) # table.headers # => ["FOO", "BAR"] # table.delete(0) # table.headers # => ["foo", "bar"] # # If the table is empty, returns a copy of the headers in the table itself: # table.delete(0) # table.headers # => ["Foo", "Bar"] # # source://csv//lib/csv/table.rb#360 def headers; end # :call-seq: # table.inspect => string # # Returns a US-ASCII-encoded \String showing table: # - Class: CSV::Table. # - Access mode: :row, :col, or :col_or_row. # - Size: Row count, including the header row. # # Example: # source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n" # table = CSV.parse(source, headers: true) # table.inspect # => "#\nName,Value\nfoo,0\nbar,1\nbaz,2\n" # # source://csv//lib/csv/table.rb#1048 def inspect; end # The current access mode for indexing and iteration. # # source://csv//lib/csv/table.rb#214 def mode; end # :call-seq: # table.push(*rows_or_arrays) -> self # # A shortcut for appending multiple rows. Equivalent to: # rows.each {|row| self << row } # # Each argument may be either a \CSV::Row object or an \Array: # source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n" # table = CSV.parse(source, headers: true) # rows = [ # CSV::Row.new(table.headers, ['bat', 3]), # ['bam', 4] # ] # table.push(*rows) # table[3..4] # => [#, #] # # source://csv//lib/csv/table.rb#788 def push(*rows); end # :call-seq: # table.to_a -> array_of_arrays # # Returns the table as an \Array of \Arrays; # the headers are in the first row: # source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n" # table = CSV.parse(source, headers: true) # table.to_a # => [["Name", "Value"], ["foo", "0"], ["bar", "1"], ["baz", "2"]] # # source://csv//lib/csv/table.rb#978 def to_a; end # :call-seq: # table.to_csv(**options) -> csv_string # # Returns the table as \CSV string. # See {Options for Generating}[../CSV.html#class-CSV-label-Options+for+Generating]. # # Defaults option +write_headers+ to +true+: # source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n" # table = CSV.parse(source, headers: true) # table.to_csv # => "Name,Value\nfoo,0\nbar,1\nbaz,2\n" # # Omits the headers if option +write_headers+ is given as +false+ # (see {Option +write_headers+}[../CSV.html#class-CSV-label-Option+write_headers]): # table.to_csv(write_headers: false) # => "foo,0\nbar,1\nbaz,2\n" # # Limit rows if option +limit+ is given like +2+: # table.to_csv(limit: 2) # => "Name,Value\nfoo,0\nbar,1\n" # # source://csv//lib/csv/table.rb#1004 def to_csv(write_headers: T.unsafe(nil), limit: T.unsafe(nil), **options); end # :call-seq: # table.to_csv(**options) -> csv_string # # Returns the table as \CSV string. # See {Options for Generating}[../CSV.html#class-CSV-label-Options+for+Generating]. # # Defaults option +write_headers+ to +true+: # source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n" # table = CSV.parse(source, headers: true) # table.to_csv # => "Name,Value\nfoo,0\nbar,1\nbaz,2\n" # # Omits the headers if option +write_headers+ is given as +false+ # (see {Option +write_headers+}[../CSV.html#class-CSV-label-Option+write_headers]): # table.to_csv(write_headers: false) # => "foo,0\nbar,1\nbaz,2\n" # # Limit rows if option +limit+ is given like +2+: # table.to_csv(limit: 2) # => "Name,Value\nfoo,0\nbar,1\n" # # source://csv//lib/csv/table.rb#1004 def to_s(write_headers: T.unsafe(nil), limit: T.unsafe(nil), **options); end # :call-seq: # table.values_at(*indexes) -> array_of_rows # table.values_at(*headers) -> array_of_columns_data # # If the access mode is :row or :col_or_row, # and each argument is either an \Integer or a \Range, # returns rows. # Otherwise, returns columns data. # # In either case, the returned values are in the order # specified by the arguments. Arguments may be repeated. # # --- # # Returns rows as an \Array of \CSV::Row objects. # # No argument: # source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n" # table = CSV.parse(source, headers: true) # table.values_at # => [] # # One index: # values = table.values_at(0) # values # => [#] # # Two indexes: # values = table.values_at(2, 0) # values # => [#, #] # # One \Range: # values = table.values_at(1..2) # values # => [#, #] # # \Ranges and indexes: # values = table.values_at(0..1, 1..2, 0, 2) # pp values # Output: # [#, # #, # #, # #, # #, # #] # # --- # # Returns columns data as row Arrays, # each consisting of the specified columns data for that row: # values = table.values_at('Name') # values # => [["foo"], ["bar"], ["baz"]] # values = table.values_at('Value', 'Name') # values # => [["0", "foo"], ["1", "bar"], ["2", "baz"]] # # source://csv//lib/csv/table.rb#734 def values_at(*indices_or_headers); end protected # Internal data format used to compare equality. # # source://csv//lib/csv/table.rb#217 def table; end end # Note: Don't use this class directly. This is an internal class. # # source://csv//lib/csv/writer.rb#8 class CSV::Writer # @return [Writer] a new instance of Writer # # source://csv//lib/csv/writer.rb#16 def initialize(output, options); end # Adds a new row # # source://csv//lib/csv/writer.rb#31 def <<(row); end # Returns the value of attribute headers. # # source://csv//lib/csv/writer.rb#14 def headers; end # 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. # # source://csv//lib/csv/writer.rb#13 def lineno; end # Winds back to the beginning # # source://csv//lib/csv/writer.rb#63 def rewind; end private # source://csv//lib/csv/writer.rb#69 def prepare; end # source://csv//lib/csv/writer.rb#105 def prepare_force_quotes_fields(force_quotes); end # source://csv//lib/csv/writer.rb#132 def prepare_format; end # source://csv//lib/csv/writer.rb#77 def prepare_header; end # source://csv//lib/csv/writer.rb#162 def prepare_output; end # source://csv//lib/csv/writer.rb#189 def quote(field, i); end # source://csv//lib/csv/writer.rb#180 def quote_field(field); end end class Object < ::BasicObject include ::Kernel include ::PP::ObjectMixin private # source://csv//lib/csv.rb#3011 def CSV(*args, **options, &block); end end # source://csv//lib/csv/core_ext/string.rb#1 class String include ::Comparable # Equivalent to CSV::parse_line(self, options) # # "CSV,data".parse_csv # #=> ["CSV", "data"] # # source://csv//lib/csv/core_ext/string.rb#6 def parse_csv(**options); end end