Bug #17387
closedAbout Warning.warn compatibility in Ruby 3.0.0
Description
The sample code in https://docs.ruby-lang.org/ja/latest/method/Warning/s/warn.html does not work in Ruby 3.0.0. Is it intended behavior? I'm worrying about its compatibility.
warn "hoge"
module Warning
def self.warn(*message)
super(*message.map { |msg| msg.chomp + "!!!\n" })
end
end
warn "hoge"
$ ruby ~/Desktop/test.rb
hoge
/Users/jnito/Desktop/test.rb:5:in `block in warn': undefined method `chomp' for {:category=>nil}:Hash (NoMethodError)
from /Users/jnito/Desktop/test.rb:5:in `map'
from /Users/jnito/Desktop/test.rb:5:in `warn'
from <internal:warning>:43:in `warn'
from /Users/jnito/Desktop/test.rb:9:in `<main>'
This issue must be related to https://bugs.ruby-lang.org/issues/17122
Updated by Eregon (Benoit Daloze) almost 4 years ago
- Related to Feature #17122: Add category to Warning#warn added
Updated by Eregon (Benoit Daloze) almost 4 years ago
The English documentation seems fine:
https://docs.ruby-lang.org/en/master/Warning.html#method-i-warn
So I guess the Japanese docs should be updated.
Updated by jnchito (Junichi Ito) almost 4 years ago
Eregon (Benoit Daloze) wrote in #note-2:
The English documentation seems fine:
https://docs.ruby-lang.org/en/master/Warning.html#method-i-warnSo I guess the Japanese docs should be updated.
Thank you for information. I noticed the first parameter can be string and array according to the method signature.
module Warning
def self.warn(message)
p message #=> "my warning\n"
super
end
end
warn "my warning"
module Warning
def self.warn(*message)
p message #=> ["my warning\n"]
super
end
end
warn "my warning"
The both can run in Ruby 2.7, but the latter won't run in Ruby 3.0.0 with the message below:
$ ruby ~/Desktop/test.rb
["my warning\n", {:category=>nil}]
/Users/jnito/Desktop/test.rb:4:in `warn': wrong number of arguments (given 2, expected 1) (ArgumentError)
from /Users/jnito/Desktop/test.rb:4:in `warn'
from <internal:warning>:43:in `warn'
from /Users/jnito/Desktop/test.rb:7:in `<main>'
Therefore, the compatibility is broken (the parameter message
should be ["my warning\n"]
). Is it a bug or not?
Updated by jeremyevans0 (Jeremy Evans) almost 4 years ago
jnchito (Junichi Ito) wrote in #note-3:
Therefore, the compatibility is broken (the parameter
message
should be["my warning\n"]
). Is it a bug or not?
It is only a bug in the Japanese documentation. Unlike Kernel#warn
, Warning.warn
in Ruby 2.7 only accepted a single string:
rb_define_method(rb_mWarning, "warn", rb_warning_s_warn, 1);
rb_extend_object(rb_mWarning, rb_mWarning);
As keywords were added to the method in Ruby 3, you can still use the keyword splat when overriding, as long as your override also uses keyword arguments:
module Warning
def self.warn(*message, **)
p message #=> ["my warning\n"]
super
end
end
warn "my warning"
This could be considered a breakage of backwards compatibility, but that is not specific to this case, it is for any method where you add keywords arguments. If you have a method that doesn't accept keyword arguments and you want to allow adding keyword arguments to the method later (safe keyword extension), you have to use the **nil
syntax (no keywords accepted). Of course, if you do this, trying to pass a final positional hash using keyword syntax will no longer work.
Updated by jnchito (Junichi Ito) almost 4 years ago
jeremyevans0 (Jeremy Evans) wrote in #note-4:
jnchito (Junichi Ito) wrote in #note-3:
Therefore, the compatibility is broken (the parameter
message
should be["my warning\n"]
). Is it a bug or not?It is only a bug in the Japanese documentation. Unlike
Kernel#warn
,Warning.warn
in Ruby 2.7 only accepted a single string:
Thank you for your comment. As for this issue, I should fix the Japanese document, so I submitted PR: https://github.com/rurema/doctree/pull/2411
Updated by mame (Yusuke Endoh) almost 4 years ago
- Status changed from Open to Closed
The Japanese doc has been fixed. This is actually an incompatibility, but I believe it is a minor issue. Thank you for the report. Closing.