RubyでCSVコンバータエンコーディングを使用するにはどうすればよいですか?
概要
require 'csv'
module Expertus
class Dataset < Array
attr_accessor :data_type, :udc_id, :filename_suffix
# knows its common_udc_id and data type
def initialize *args
CSV::Converters[:non_octal_integer] = lambda { |f|
begin
e = f.encode(CSV::ConverterEncoding)
unless e == "0"
if e.starts_with? "0"
return f
end
end
rescue
return f
end
Integer(f.encode(CSV::ConverterEncoding)) rescue f
}
CSV::Converters[:non_octal_float] = lambda { |f|
begin
e = f.encode(CSV::ConverterEncoding)
unless e.starts_with? "0."
if e.starts_with? "0"
return f
end
end
rescue
return f
end
Float(f.encode(CSV::ConverterEncoding)) rescue f
}
CSV::Converters[:string_to_bool] =->(f) {
['true', 'false'].include?(f) ? f=='true' : f
}
@csv_options = {:converters => [:non_octal_integer, :non_octal_float, :string_to_bool]}
@data_type = nil
@udc_id = nil
@filename_suffix = nil
super
end
def expected_output_filename
return "#{@udc_id}_#{@data_type}#{@filename_suffix}.csv"
end
def read_expected_output_file_from_directory! directory
if directory.is_a? String
p "Directory/File:::: #{File.join(directory, self.expected_output_filename)}"
p "@csv_options::: #{@csv_options}"
csv_data = CSV.read File.join(directory, self.expected_output_filename), @csv_options
else
csv_data = CSV.new(directory, @csv_options).read
end
csv_data[0].map! { |h| h.to_sym }
self.clear
self.replace csv_data
end
次のように jRuby スクリプトで read_expected_output_file_from_directory メソッドを呼び出しています。
expected_dataset.read_expected_output_file_from_directory! File.join($session.script_dir, '..', 'expectedresults')
エラーがスローされます:
[“引数の数が間違っています (2 が指定され、1 が期待されます) (ArgumentError)”]
[“引数の数が間違っています (2 が指定され、1 が期待されます) (ArgumentError)”]
助けていただければ幸いです。ありがとう
@Stefanと@Ilmari Karonenが提案したように、これで機能したもの:
def read_expected_output_file_from_directory! directory
if directory.is_a? String
p "Directory/File:::: #{File.join(directory, self.expected_output_filename)}"
p "@csv_options::: #{@csv_options}"
csv_data = CSV.read File.join(directory, self.expected_output_filename), **@csv_options**
else
csv_data = CSV.new(directory, **@csv_options**).read
end
csv_data[0].map! { |h| h.to_sym }
self.clear
self.replace csv_data
end
解決策
Stefan が上記のコメントで述べているように、CSV.read と CSV.new はオプションがキーワード引数として渡されることを期待しています。
** を使用してハッシュをキーワード引数に変換できます。例:
CSV.new(directory, **@csv_options)
Ruby 2 (および JRuby 9.3) では、キーワード引数を期待するメソッドに最後の引数としてハッシュを渡すことができ、暗黙的にキーワード引数に変換されます。ただし、Ruby 3 (および JRuby 9.4) では、** を使用して明示的に要求しない限り、これは発生しなくなりました。