diff options
-rw-r--r-- | NEWS.md | 8 | ||||
-rw-r--r-- | error.c | 30 | ||||
-rw-r--r-- | test/ruby/test_exception.rb | 24 |
3 files changed, 54 insertions, 8 deletions
@@ -165,6 +165,13 @@ Outstanding ones only. * Symbol#to_proc now returns a lambda Proc. [[Feature #16260]] +* Warning + + * Modified method + + * Warning#warn now supports a category kwarg. + [[Feature #17122]] + ## Stdlib updates Outstanding ones only. @@ -342,3 +349,4 @@ Excluding feature bug fixes. [Feature #16686]: https://bugs.ruby-lang.org/issues/16686 [Misc #16961]: https://bugs.ruby-lang.org/issues/16961 [Bug #8446]: https://bugs.ruby-lang.org/issues/8446 +[Feature #17122]: https://bugs.ruby-lang.org/issues/17122 @@ -229,15 +229,20 @@ rb_warning_s_aset(VALUE mod, VALUE category, VALUE flag) /* * call-seq: - * warn(msg) -> nil + * warn(msg, **kw) -> nil * * Writes warning message +msg+ to $stderr. This method is called by - * Ruby for all emitted warnings. + * Ruby for all emitted warnings. A +category+ may be included with + * the warning. */ static VALUE -rb_warning_s_warn(VALUE mod, VALUE str) +rb_warning_s_warn(int argc, VALUE *argv, VALUE mod) { + VALUE str; + VALUE opt; + + rb_scan_args(argc, argv, "1:", &str, &opt); Check_Type(str, T_STRING); rb_must_asciicompat(str); rb_write_error_str(str); @@ -401,7 +406,22 @@ rb_warn_deprecated_to_remove(const char *fmt, const char *removal, ...) va_end(args); rb_str_set_len(mesg, RSTRING_LEN(mesg) - 1); rb_str_catf(mesg, " is deprecated and will be removed in Ruby %s\n", removal); - rb_write_warning_str(mesg); + + VALUE warn_args[2]; + warn_args[0] = mesg; + + const rb_method_entry_t * me; + me = rb_method_entry(rb_mWarning, id_warn); + + if (rb_method_entry_arity(me) != 1) { + VALUE kwargs = rb_hash_new(); + rb_hash_aset(kwargs, ID2SYM(rb_intern("category")), ID2SYM(rb_intern("deprecated"))); + warn_args[1] = kwargs; + + rb_funcallv_kw(rb_mWarning, id_warn, 2, warn_args, RB_PASS_KEYWORDS); + } else { + rb_funcall(rb_mWarning, id_warn, 1, mesg); + } } static inline int @@ -2658,7 +2678,7 @@ Init_Exception(void) rb_mWarning = rb_define_module("Warning"); rb_define_singleton_method(rb_mWarning, "[]", rb_warning_s_aref, 1); rb_define_singleton_method(rb_mWarning, "[]=", rb_warning_s_aset, 2); - rb_define_method(rb_mWarning, "warn", rb_warning_s_warn, 1); + rb_define_method(rb_mWarning, "warn", rb_warning_s_warn, -1); rb_extend_object(rb_mWarning, rb_mWarning); /* :nodoc: */ diff --git a/test/ruby/test_exception.rb b/test/ruby/test_exception.rb index 4decddc273..a89aed8806 100644 --- a/test/ruby/test_exception.rb +++ b/test/ruby/test_exception.rb @@ -915,7 +915,7 @@ $stderr = $stdout; raise "\x82\xa0"') do |outs, errs, status| end end - def capture_warning_warn + def capture_warning_warn(category: false) verbose = $VERBOSE deprecated = Warning[:deprecated] warning = [] @@ -924,8 +924,14 @@ $stderr = $stdout; raise "\x82\xa0"') do |outs, errs, status| alias_method :warn2, :warn remove_method :warn - define_method(:warn) do |str| - warning << str + if category + define_method(:warn) do |str, **kw| + warning << [str, kw[:category]] + end + else + define_method(:warn) do |str| + warning << str + end end end @@ -954,6 +960,18 @@ $stderr = $stdout; raise "\x82\xa0"') do |outs, errs, status| assert_equal(["\n"], capture_warning_warn {warn ""}) end + def test_warn_backwards_compatibility + warning = capture_warning_warn { Object.new.tainted? } + + assert_match(/deprecated/, warning[0]) + end + + def test_warn_category + warning = capture_warning_warn(category: true) { Object.new.tainted? } + + assert_equal :deprecated, warning[0][1] + end + def test_kernel_warn_uplevel warning = capture_warning_warn {warn("test warning", uplevel: 0)} assert_equal("#{__FILE__}:#{__LINE__-1}: warning: test warning\n", warning[0]) |