From 8fde54a3b5073d10aff10d359a3f10818d57ea2c Mon Sep 17 00:00:00 2001 From: Anthony Hernandez Date: Mon, 10 May 2021 17:41:26 -0700 Subject: [PATCH] [ruby/csv] CSV(): Add support for Ruby 3 (https://github.com/ruby/csv/pull/215) The implementation of the `CSV` shortcut method is broken in Ruby 3 for calls that look like this: ```ruby CSV(write_stream, col_sep: "|", headers: headers, write_headers: true) do |csv| ... end ``` The above will result in the following error when the `CSV` method attempts to pass on arguments to `CSV#instance`: ``` ArgumentError: wrong number of arguments (given 2, expected 0..1) ``` The issue is due to the changes in Ruby 3 relating to positional & keyword arguments. This commit updates the `CSV()` shortcut implementation to work with Ruby 3, and also updates the documentation for the shortcut method. https://github.com/ruby/csv/commit/310dee45fa --- lib/csv.rb | 9 +++++++-- test/csv/interface/test_read_write.rb | 9 +++++++++ 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/lib/csv.rb b/lib/csv.rb index 91aeb19a3c..87c3a4be31 100644 --- a/lib/csv.rb +++ b/lib/csv.rb @@ -2650,8 +2650,13 @@ end # c.read.any? { |a| a.include?("zombies") } # } #=> false # -def CSV(*args, &block) - CSV.instance(*args, &block) +# CSV options may also be given. +# +# io = StringIO.new +# CSV(io, col_sep: ";") { |csv| csv << ["a", "b", "c"] } +# +def CSV(*args, **options, &block) + CSV.instance(*args, **options, &block) end require_relative "csv/version" diff --git a/test/csv/interface/test_read_write.rb b/test/csv/interface/test_read_write.rb index 20c9fe317e..c371e9c5fc 100644 --- a/test/csv/interface/test_read_write.rb +++ b/test/csv/interface/test_read_write.rb @@ -112,4 +112,13 @@ a;b;c assert_equal(CSV.instance, CSV {|csv| csv}) end + + def test_instance_shortcut_with_io + io = StringIO.new + from_instance = CSV.instance(io, col_sep: ";") { |csv| csv << ["a", "b", "c"] } + from_shortcut = CSV(io, col_sep: ";") { |csv| csv << ["e", "f", "g"] } + + assert_equal(from_instance, from_shortcut) + assert_equal(from_instance.string, "a;b;c\ne;f;g\n") + end end