From: nobu@... Date: 2017-10-19T06:19:25+00:00 Subject: [ruby-core:83374] [Ruby trunk Feature#12882] Add caller/file/line information to internal Kernel#warn calls Issue #12882 has been updated by nobu (Nobuyoshi Nakada). ```diff diff --git a/error.c b/error.c index 9bd8c31386..499212cdd8 100644 --- a/error.c +++ b/error.c @@ -321,10 +321,28 @@ end_with_asciichar(VALUE str, int c) static VALUE rb_warn_m(int argc, VALUE *argv, VALUE exc) { - if (!NIL_P(ruby_verbose) && argc > 0) { + VALUE opts, uplevel = Qnil; + + if (!NIL_P(ruby_verbose) && argc > 0 && + (argc = rb_scan_args(argc, argv, "*:", NULL, &opts)) > 0) { VALUE str = argv[0]; - if (argc > 1 || !end_with_asciichar(str, '\n')) { - str = rb_str_tmp_new(0); + if (!NIL_P(opts)) { + static ID kwds[1]; + if (!kwds[0]) CONST_ID(kwds[0], "uplevel"); + rb_get_kwargs(opts, kwds, 0, 1, &uplevel); + if (uplevel == Qundef) { + uplevel = Qnil; + } + else if (!NIL_P(uplevel)) { + uplevel = LONG2NUM((long)NUM2ULONG(uplevel) + 1); + uplevel = rb_vm_thread_backtrace(1, &uplevel, GET_THREAD()->self); + if (!NIL_P(uplevel)) { + uplevel = rb_ary_entry(uplevel, 0); + } + } + } + if (argc > 1 || !NIL_P(uplevel) || !end_with_asciichar(str, '\n')) { + str = NIL_P(uplevel) ? rb_str_tmp_new(0) : rb_str_cat_cstr(uplevel, ": "); RBASIC_SET_CLASS(str, rb_cWarningBuffer); rb_io_puts(argc, argv, str); RBASIC_SET_CLASS(str, rb_cString); ``` ---------------------------------------- Feature #12882: Add caller/file/line information to internal Kernel#warn calls https://bugs.ruby-lang.org/issues/12882#change-67332 * Author: jeremyevans0 (Jeremy Evans) * Status: Feedback * Priority: Normal * Assignee: matz (Yukihiro Matsumoto) * Target version: ---------------------------------------- Most internal uses of Kernel#warn do not begin with caller/file/line information, making debugging such warnings more difficult, and hindering filtering/processing of warnings on a per-file/directory/gem basis when overriding Warning.warn (a new feature in ruby 2.4). I think it would be better if internal calls to Kernel#warn in ruby code included caller information, so the warnings generated are similar to those generated by rb_warn in C code. I'm attaching an initial attempt at this. There was a lot of internal inconsistency in existing warning messages that include caller information. I choose to standardize on `caller(1,1).first`. Specifying 1 as the length argument to caller provides a 5-10x speedup compared to the default of nil as the length argument, and since warning messages only use the first line, there's no need to generate additional lines. I also benchmarked using caller_locations, but that didn't seem to perform better, probably because the result is just converted to a string anyway. Some existing warning messages that include caller information use #caller but attempt to strip out the method information via gsub. I'm guessing it would be better to use #caller_locations. However, that's kind of cumbersome right now, if we want to do that, we should probably add a method to Thread::Backtrace::Location that returns just the absolute_path and lineno as a string, so we could standardize on `caller_locations(1,1).first.file_and_line` (or whatever the method is called). There are a few questionable changes in the attached patch, such as the use of `caller(0,1)` in certain cases (when the changes were at top level), or including caller information in warning messages that were only output in DEBUG mode. The attached patch does not include changes for rdoc and rubygems, as those are maintained in separate repositories. Assuming that this patch or a similar one is accepted, I can submit patches to both rdoc and rubygems for their warning messages. ---Files-------------------------------- 0001-Prepend-warning-messages-with-caller-information.patch (30.6 KB) -- https://bugs.ruby-lang.org/ Unsubscribe: