ArgumentError (wrong number of arguments (given 2, expected 1)) after updating to Ruby 3.0
Asked Answered
B

1

8

When I try to update our site to Ruby 3.0.0 I get this error:

ArgumentError (wrong number of arguments (given 2, expected 1))

 % rails console
Loading development environment (Rails 6.1.0)
irb(main):001:0> puts RUBY_VERSION
3.0.0
irb(main):002:0> puts IceCube::VERSION
0.16.3
irb(main):003:0> schedule = IceCube::Schedule.new
=> #<IceCube::Schedule:0x00007fccfe19cfa8 @start_time=2020-12-27 11:14:30 -0800, @all_recurrence_rules=[], @all_exception_rules=[]>
irb(main):004:0> puts schedule.to_ical
Traceback (most recent call last):
        1: from (irb):4:in `<main>'
ArgumentError (wrong number of arguments (given 2, expected 1))

Here are the same commands with Ruby 2.7.2 which work

% rails console
Loading development environment (Rails 6.1.0)
irb(main):001:0> puts RUBY_VERSION
2.7.2
irb(main):002:0> puts IceCube::VERSION
0.16.3
irb(main):003:0> schedule = IceCube::Schedule.new
=> #<IceCube::Schedule:0x00007f9da3128fe8 @start_time=2020-12-27 11:12:50 -0800, @all_recurrence_rules=[], @all_exception_rules=[]>
irb(main):004:0> puts schedule.to_ical
DTSTART;TZID=PST:20201227T111250

What's confusing is that it also works with a plain ruby script with the same gem versions as the first example

% irb
irb(main):001:0> puts RUBY_VERSION
3.0.0
irb(main):002:0> gem 'ice_cube'
irb(main):003:0> require 'ice_cube'
irb(main):004:0> puts IceCube::VERSION
0.16.3
irb(main):005:0> schedule = IceCube::Schedule.new
=> #<IceCube::Schedule:0x00007ff2fb0d5b88 @start_time=2020-12-27 11:11:02 -0800, @all_recurrence_rules=[], @all_exception_rules=[]>
irb(main):006:0> puts schedule.to_ical
DTSTART;TZID=PST:20201227T111102

Does anyone know where I can start to fix this? We're just starting the project and I am hoping to use Ruby 3

Biparous answered 27/12, 2020 at 19:33 Comment(0)
B
9

TL;DR: ice_cube 0.16.4 has already sorted out these compatibility problems with ruby 3.x, so just upgrade.


The issue has to do with how keyword arguments are handled in ruby 3.0 and how ice_cube is passing its arguments to I18n.localize.
So, extracting and simplifying the buggy code, this worked on ruby < 3

RUBY_VERSION # "2.7.2"

def foo(*args)
  bar(*args)
end

def bar(object, locale: nil, format: nil, **options)
  puts "object:#{object}"
  puts "locale:#{locale}"
  puts "format:#{format}"
  puts "options:#{options}"
end

foo('date', format: 'whatever')
# object:date
# locale:
# format:whatever
# options:{}

And from ruby >= 3

RUBY_VERSION # "3.0.0"

def foo(*args)
  bar(*args)
end

def bar(object, locale: nil, format: nil, **options)
  puts "object:#{object}"
  puts "locale:#{locale}"
  puts "format:#{format}"
  puts "options:#{options}"
end

foo('date', format: 'whatever')
# Traceback (most recent call last):
#        16: from /Users/alter/.rbenv/versions/3.0.0/lib/ruby/3.0.0/bundler/cli.rb:24:in `start'
#        15: from /Users/alter/.rbenv/versions/3.0.0/lib/ruby/3.0.0/bundler/vendor/thor/lib/thor/base.rb:485:in `start'
#        14: from /Users/alter/.rbenv/versions/3.0.0/lib/ruby/3.0.0/bundler/cli.rb:30:in `dispatch'
#        13: from /Users/alter/.rbenv/versions/3.0.0/lib/ruby/3.0.0/bundler/vendor/thor/lib/thor.rb:392:in `dispatch'
#        12: from /Users/alter/.rbenv/versions/3.0.0/lib/ruby/3.0.0/bundler/vendor/thor/lib/thor/invocation.rb:127:in `invoke_command'
#        11: from /Users/alter/.rbenv/versions/3.0.0/lib/ruby/3.0.0/bundler/vendor/thor/lib/thor/command.rb:27:in `run'
#        10: from /Users/alter/.rbenv/versions/3.0.0/lib/ruby/3.0.0/bundler/cli.rb:497:in `exec'
#         9: from /Users/alter/.rbenv/versions/3.0.0/lib/ruby/3.0.0/bundler/cli/exec.rb:28:in `run'
#         8: from /Users/alter/.rbenv/versions/3.0.0/lib/ruby/3.0.0/bundler/cli/exec.rb:63:in `kernel_load'
#         7: from /Users/alter/.rbenv/versions/3.0.0/lib/ruby/3.0.0/bundler/cli/exec.rb:63:in `load'
#         6: from /Users/alter/.rbenv/versions/3.0.0/bin/irb:23:in `<top (required)>'
#         5: from /Users/alter/.rbenv/versions/3.0.0/bin/irb:23:in `load'
#         4: from /Users/alter/.rbenv/versions/3.0.0/lib/ruby/gems/3.0.0/gems/irb-1.3.0/exe/irb:11:in `<top (required)>'
#         3: from (irb):11:in `<main>'
#         2: from (irb):3:in `foo'
#         1: from (irb):5:in `bar'
# ArgumentError (wrong number of arguments (given 2, expected 1))

So, the fix I can see is to explicitely passing the parameters to the method:

def foo2(object, **options)
  bar(object, **options)
end

foo2('date', format: 'whatever')
# object:date
# locale:
# format:whatever
# options:{}

Or in terms of the involved module:

module IceCube
  module I18n
    def self.l(object, **options)
      backend.l(object, **options)
    end
  end
end

and send a PR, use your own fork, monkey-patch, whatever works best for you.
But most important, brace yourself to find this issue in a lot of other gems, as the first stable ruby 3 version was just released 2 days ago, so probably you'll have these type of issues with other gems, specially the unmaintained ones. Good luck.

Biochemistry answered 27/12, 2020 at 23:32 Comment(5)
I forked the project to github.com/sthapit/ice_cube -- could you let me know what I should put in ice_cube/lib/ice_cube/i18n.rb to get this to work? This is a fairly popular gem so I assume it will be useful for many peopleBiparous
Check the changes I put in self.l method and apply them in your forkBiochemistry
I removed the delegated localize method and added your code and it works great github.com/sthapit/ice_cube/blob/master/lib/ice_cube/i18n.rb -- before I send a PR does something similar also need to be done for the translate method that was being delegated together with localize?Biparous
that works!! thank you so much -- I have accepted the answer and we'll also be using the master branchBiparous
I wish I understood any of this. So confusing.Lithiasis

© 2022 - 2024 — McMap. All rights reserved.