7

We want to update our codebase to Ruby 3 and one of the biggest breaking change is the mix of keyword arguments with arguments in methods. This warning should show up

warning: Using the last argument as keyword parameters is deprecated; maybe ** should be added to the call

But I've noticed when running a simple script, it just doesn't appear

# script.rb
def my_method(argument, other:)
  puts "hello"
end

options = { other: "medium" }
argument = true

my_method(argument, options)

$ rvm use 2.7.5
$ ruby script.rb
hello

$ rvm use 3.0.1
$ ruby script.rb
script.rb:1:in `my_method': wrong number of arguments (given 2, expected 1; required keyword: other) (ArgumentError)
    from script.rb:8:in `<main>'

It breaks as planned in Ruby 3, but doesn't show anything in the previous versions.

This behavior is the same in production for us, I couldn't spot one occurrence anywhere. I've used RUBYOPT='-W:deprecated' or even $VERBOSE = true that successfully list several other deprecation warnings except this one.

After looking around, it doesn't seem other people have this problem. Is there something I am missing here? Is there an option in Ruby? Using other versions of Ruby like 2.7.2 renders the same.

Another detail, we use Ruby on Rails ton run everything, but I believe the problem is within Ruby itself.

Laurent
  • 2,284
  • 2
  • 21
  • 41

1 Answers1

7

I've discovered a few things. First of all, Ruby 2.7.2 and later don't show warnings by default which would explain the difference of behavior in my tests. To activate them you have to use RUBYOPT

# Ruby 2.7.5
$ RUBYOPT='-W:deprecated' ruby script.rb
script.rb:8: warning: Using the last argument as keyword parameters is deprecated; maybe ** should be added to the call
script.rb:1: warning: The called method `my_method' is defined here
hello

Another point is that the $VERBOSE = true you can set later on doesn't work either to show this warning. I'm not sure exactly why, but only RUBYOPT would do the job for this specific problem.

Finally, I also had used wrongly the RUBYOPT option when starting my Rails server locally thus not seeing it working.

I hope it helps.

Laurent
  • 2,284
  • 2
  • 21
  • 41
  • "Ruby 2.7.2 and later don't show warnings by default " – No version of Ruby has ever shown warnings by default. In fact, almost no language implementation I know of shows warnings by default. – Jörg W Mittag Apr 07 '22 at 00:54
  • 1
    you should also fix your code. don't just ignore warnings. – Jad Apr 07 '22 at 08:28
  • 1
    @JörgWMittag https://www.ruby-lang.org/en/news/2020/10/02/ruby-2-7-2-released/ they say here something was turned off though – Laurent Apr 19 '22 at 18:39
  • @Jad of course my plan is to fix the whole codebase thanks to those warnings – Laurent Apr 19 '22 at 18:39
  • 1
    Just a note that after Ruby 2.7.2 switched to having deprecation warnings off by default, Minitest was updated to set `Warning[:deprecated] = true` [here](https://github.com/minitest/minitest/pull/871). So far RSpec has chosen [not to make a similar change](https://github.com/rspec/rspec-core/issues/2867). – cschroed Apr 03 '23 at 15:46