Feature #11460
closedUnhelpful error message when naming a module with the same name as an existing class
Description
Summary¶
The error message when naming a module with the same name as an existing class causes more trouble then it helps.
Steps to Reproduce¶
class X;end
module X;end
=> TypeError: X is not a module
Expected Results¶
Ruby has this very helpful and explicit error when reassigning a value to an existing constant.
A = 1
A = 2
warning: already initialized constant A
warning: previous definition of A was here
which makes me expect Ruby to keep track of names of global constants and prevent me from colliding names with helpful warnings. This warning however raises a "Type error" which is not very intuitive. When users think of type errors they think of things like "foo" * "foo" => TypeError: no implicit conversion of String into Integer.
Actual Results¶
Confusion about what the actual error is, especially for people learning Ruby.
Files
Updated by jeremyevans0 (Jeremy Evans) over 5 years ago
- File mod-reopen-error-message.patch mod-reopen-error-message.patch added
- Status changed from Open to Feedback
The reason for the difference in behavior here is due to Ruby's open classes. When using class X
or module X
, if the constant X
is already defined, Ruby will reopen the class or module definition, so you can operate in the context of the class or module. However, attempting to reopen a class when the object is not actually a class is a error, whereas reassigning a constant is just a warning.
The warning message you get during constant reassignment is used for classes and modules if you assign them:
X = Class.new
X = Module.new
# warning: already initialized constant X
# warning: previous definition of X was here
Likewise, the error raised when attempting to reopening an existing constant is pretty much the same for all objects that don't match the expected type:
X = 1
class X; end
# TypeError (X is not a class)
module X; end
# TypeError (X is not a module)
So I don't think there is a bug here. It is possible to change the format the error message, though. Attached is a patch that changes the error message to the include the current class of the object:
class X;end
module X;end
# TypeError (X is not a module, it is a Class)
module Y;end
class Y;end
# TypeError (Y is not a class, it is a Module)
I would appreciate feedback on whether this more detailed error message is an improvement.
Updated by duerst (Martin Dürst) over 5 years ago
jeremyevans0 (Jeremy Evans) wrote:
So I don't think there is a bug here. It is possible to change the format the error message, though. Attached is a patch that changes the error message to the include the current class of the object:
class X;end module X;end # TypeError (X is not a module, it is a Class) module Y;end class Y;end # TypeError (Y is not a class, it is a Module)
I would appreciate feedback on whether this more detailed error message is an improvement.
I think it is.
Updated by nobu (Nobuyoshi Nakada) over 5 years ago
Is “a Integer” OK? :)
Updated by sawa (Tsuyoshi Sawada) over 5 years ago
nobu (Nobuyoshi Nakada) wrote:
Is “a Integer” OK? :)
"a(n) Integer"
Updated by nobu (Nobuyoshi Nakada) over 5 years ago
- File 0001-Show-the-previous-definition-location.patch 0001-Show-the-previous-definition-location.patch added
- Tracker changed from Bug to Feature
- ruby -v deleted (
ruby 2.2.0p0) - Backport deleted (
2.0.0: UNKNOWN, 2.1: UNKNOWN, 2.2: UNKNOWN)
Updated by shevegen (Robert A. Heiler) over 5 years ago
I would appreciate feedback on whether this more detailed error message is an improvement.
I think this depends on what the ruby user at hand is doing; and how much expertise that
ruby user may have. Some behaviour in ruby can be confusing to newcomers, such as when
variables may be assigned to nil, without explicit "x = nil
".
I personally do not really need a change either way in the context of this suggestion (I
am fine with the current behaviour), but I think it is not completely unreasonable to
assume that there could be use cases for letting ruby be more verbose in this (or
similar) situation, if it leads to an improvement such as less confusion for newcomers.
In the long run it may be good to sort of have ruby in different "modes"; a bit like
the did-you-mean gem and the -w flag for running ruby code, but with more control over
the messages (as long as they are just warnings, but perhaps also some that relate to
errors, in particular when ruby interacts with the user). But as written before, I am
really mostly neutral either way - not really decidedly adopting any pro or con
opinion, just commenting to the question by jeremy. :-)
Updated by matz (Yukihiro Matsumoto) over 5 years ago
Accepted.
Matz.
Updated by nobu (Nobuyoshi Nakada) over 5 years ago
- Status changed from Feedback to Closed
Applied in changeset git|761346a9604ca2c79777d1d67fb5dcc3c30dbf69.
Show the previous definition location,
when reopened class/module redefinition mismatched the previous
definition. [Feature #11460]