ruby-changes:61377
From: Jean <ko1@a...>
Date: Tue, 26 May 2020 14:10:55 +0900 (JST)
Subject: [ruby-changes:61377] 385ac07fd8 (master): Use receiver #name rather than #inspect to build NameError message
https://git.ruby-lang.org/ruby.git/commit/?id=385ac07fd8 From 385ac07fd8f5a50825aee8db459086e617f492aa Mon Sep 17 00:00:00 2001 From: Jean Boussier <jean.boussier@g...> Date: Mon, 4 May 2020 16:56:45 +0200 Subject: Use receiver #name rather than #inspect to build NameError message diff --git a/error.c b/error.c index 31ffc32..553f9c7 100644 --- a/error.c +++ b/error.c @@ -1763,6 +1763,17 @@ name_err_mesg_equal(VALUE obj1, VALUE obj2) https://github.com/ruby/ruby/blob/trunk/error.c#L1763 /* :nodoc: */ static VALUE +name_err_mesg_receiver_name(VALUE obj) +{ + if (RB_SPECIAL_CONST_P(obj)) return Qundef; + if (RB_BUILTIN_TYPE(obj) == T_MODULE || RB_BUILTIN_TYPE(obj) == T_CLASS) { + return rb_check_funcall(obj, rb_intern("name"), 0, 0); + } + return Qundef; +} + +/* :nodoc: */ +static VALUE name_err_mesg_to_str(VALUE obj) { VALUE *ptr, mesg; @@ -1789,7 +1800,9 @@ name_err_mesg_to_str(VALUE obj) https://github.com/ruby/ruby/blob/trunk/error.c#L1800 d = FAKE_CSTR(&d_str, "false"); break; default: - d = rb_protect(rb_inspect, obj, &state); + d = rb_protect(name_err_mesg_receiver_name, obj, &state); + if (state || d == Qundef || d == Qnil) + d = rb_protect(rb_inspect, obj, &state); if (state) rb_set_errinfo(Qnil); if (NIL_P(d)) { diff --git a/spec/ruby/language/constants_spec.rb b/spec/ruby/language/constants_spec.rb index 95b0dca..4789723 100644 --- a/spec/ruby/language/constants_spec.rb +++ b/spec/ruby/language/constants_spec.rb @@ -154,6 +154,36 @@ describe "Literal (A::X) constant resolution" do https://github.com/ruby/ruby/blob/trunk/spec/ruby/language/constants_spec.rb#L154 -> { ConstantSpecs::ParentA::CS_CONSTX }.should raise_error(NameError) end + ruby_version_is "2.8" do + it "uses the module or class #name to craft the error message" do + mod = Module.new do + def self.name + "ModuleName" + end + + def self.inspect + "<unusable info>" + end + end + + -> { mod::DOES_NOT_EXIST }.should raise_error(NameError, /uninitialized constant ModuleName::DOES_NOT_EXIST/) + end + + it "uses the module or class #inspect to craft the error message if they are anonymous" do + mod = Module.new do + def self.name + nil + end + + def self.inspect + "<unusable info>" + end + end + + -> { mod::DOES_NOT_EXIST }.should raise_error(NameError, /uninitialized constant <unusable info>::DOES_NOT_EXIST/) + end + end + it "sends #const_missing to the original class or module scope" do ConstantSpecs::ClassA::CS_CONSTX.should == :CS_CONSTX end -- cgit v0.10.2 -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/