Introduce NotImplementedYetError exception that should be used in case when the codepath has not been implemented by the developer for some reason (maybe they're designing an abstract class or are designing some sort of interface to reuse later on) OR extend the meaning of NotImplementedError to cover those usecases so we don't have to introduce another exception
However it appears that many people are misusing this exception by raising this in a superclass from which they later inherit from. I do realize that Ruby promotes duck-typing (the default RuboCop style guide has a cop for this – https://github.com/rubocop/ruby-style-guide#duck-typing). However I have seen this being discussed numerous times:
I think a new exception is a better idea than changing the usage of an existing one just because "everyone is using it". That said it would require people to refactor their code which might prevent wider adoption of the new exception.
Change scope of NotImplementedError
This would require the least amount of changes possible (only a documentation change) and I believe there would be no compatibility problems whatsoever.
Subject changed from New error class: NotImplementedYetError or scope change for NotImplementedYet to New error class: NotImplementedYetError or scope change for NotImplementedError
Attached is a patch to update the documentation for NotImplementedError to expand its scope beyond just missing features on the underlying platform.
The current documentation has been in place since just before Ruby 1.9.2. Historically, it appears that Ruby hasn't limited its usage of NotImplementedError to errors that originate from features missing from the underlying platform (e.g. system calls) since at least 1.8.0. I believe the example provided in the current NotImplementedError documentation was meant as an example, not to suggest the only scope in which this error can be used.
Ruby itself invalidates most of the interpretation provided in the Background section of this ticket. Here are just three examples:
numeric.c raises NotImplementedError when a class needs provide its own <=> method.
delegate.rb raises NotImplementedError to indicate that a getobj and setobj need to provided by a subclass.
tsort uses this error and documents it expressly as: Should be implemented by a extended class.
There are more examples to be found in Ruby as well.
Outside of Ruby, this pattern is also commonly used as a way to communicate the intent to an application, framework, or library developer. Here are four examples from popular projects:
I'm guilty of using NotImplementedError for abstract classes. I like the idea of changing the documentation, but on the other hand, since NotImplementedError doesn't inherit from StandardError I kind of wish there was a new exception class.
tenderlovemaking (Aaron Patterson) wrote in #note-8:
I'm guilty of using NotImplementedError for abstract classes. I like the idea of changing the documentation, but on the other hand, since NotImplementedError doesn't inherit from StandardError I kind of wish there was a new exception class.
Hence my proposal to introduce a new class. I didn't want to create a PR for either solution because I would welcome both of them. I'm slightly leaning towards a new exception class for this.
since NotImplementedError doesn't inherit from StandardError I kind of wish there was a new exception class
Could you elaborate? For this use case I think not inheriting from StandardError is better, as it's not something you'd want to be rescued broadly.
It is something I would like rescued broadly. For example if I'm test driving a concrete implementation, the test framework needs to specifically rescue NotImplementedError in order to report the error. I wouldn't expect a test framework to rescue OutOfMemoryError for example, but definitely rescue NotImplementedError.
Agreed. If people want an exception that inherits from StandardError, then NoMethodError perfectly fits the bill.
I still think that "you forgot to implement this abstract method" shouldn't inherit from StandardError though, as it risk getting handled by the application and not surface during testing, hence why NotImplementedError already works great for that use case regardless of what the documentation says.
This exception is derived from RuntimeError. In user defined base classes, abstract methods should raise this exception when they require derived classes to override the method, or while the class is being developed to indicate that the real implementation still needs to be added.
It's a bit off-topic but does anyone know why NotImplementedError doesn't inherit from StandardError? It seems like it should. If the system doesn't support fork() then I'd like to see that as a nice message via Rack::ShowExceptions rather than having to dig through logs.
And if you use it for abstract classes then you definitely want that displayed by Rack::ShowExceptions