[前][次][番号順一覧][スレッド一覧]

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/

[前][次][番号順一覧][スレッド一覧]