summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--error.c15
-rw-r--r--spec/ruby/language/constants_spec.rb30
2 files changed, 44 insertions, 1 deletions
diff --git a/error.c b/error.c
index 31ffc32723..553f9c7daa 100644
--- a/error.c
+++ b/error.c
@@ -1763,6 +1763,17 @@ name_err_mesg_equal(VALUE obj1, VALUE obj2)
/* :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)
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 95b0dcace9..47897234b9 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
-> { 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