Issue #16832 has been updated by byroot (Jean Boussier).


> (also #name can be nil, and calling #name on arbitrary objects could easily be worse than #inspect).

So the issue title is no longer relevant. Since then I dug more into this issue, and I think the behavior should be similar to `rb_profile_frame_classpath`, in short try to use `rb_class2name` for T_MODULE and T_CLASS, see this PR for instance: https://github.com/ruby/ruby/pull/3084

I'll try to better explain my reasoning:

  - `#inspect` semantic is to describe an object
  - `uninitialized constant` error message tells you about a missing constant, constants are not objects, they are references to objects.
  - So that message should try to tell you the name of the missing constant (AKA class path) rather than describe the object that was supposed to hold the constant.

The fact is, that message builder basically does `"#{receiver.inspect}::#{missing_constant_name}"`, that joining `::` indicates that it assumes `receiver.inspect` returned a class path.

----------------------------------------
Feature #16832: Use #name rather than #inspect to build "uninitialized constant" error messages
https://bugs.ruby-lang.org/issues/16832#change-85524

* Author: byroot (Jean Boussier)
* Status: Open
* Priority: Normal
----------------------------------------
While debugging a bug in Rails (https://github.com/rails/rails/pull/37632#issuecomment-623387954) I noticed `NameError` calls `inspect` on the `const_get` receiver to build its error message.

The problem is that some libraries such as Active Record have been redefining `inspect` for years to provide human readable information, e.g.: 

```
>> Shipit::Stack.inspect
=> "Shipit::Stack (call 'Shipit::Stack.connection' to establish a connection)"
>> Shipit::Stack.connection; nil
>> Shipit::Stack.inspect
=> "Shipit::Stack(id: integer, environment: string, ...)"
```

Which makes for fairly unhelpful error messages:

```
>> Shipit::Stack.const_get(:Foo)
Traceback (most recent call last):
        2: from (irb):4
        1: from (irb):4:in `const_get'
NameError (uninitialized constant #<Class:0x00007fc8cadf2dd0>::Foo)
```

So perhaps it's Active Record that is at fault here, but from my understanding since the goal is to display the constant path that was requested, `name` is much more likely to return a relevant constant name.

Proposed patch: https://github.com/ruby/ruby/pull/3080



-- 
https://bugs.ruby-lang.org/

Unsubscribe: <mailto:ruby-core-request / ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-core>