Misusing of NotImplementedError in Ruby
Have you ever come across code that raises a
NotImplementedError when a method is not implemented in a class? It may seem like a convenient way to indicate that a method should be implemented, but actually it’s not.
According to the Ruby docs,
NotImplementedError should be used when a feature is not implemented on the current platform. It’s typically used in operating-system-dependent methods to indicate that the current runtime platform does not support certain functionality.
For example, if a method depends on the
fork system calls, raising a
NotImplementedError would be appropriate if the underlying operating system or Ruby runtime doesn’t support them.
def save_data(data, file_path)
File.open(file_path, 'w') do |file|
raise 'The fsync system call is not supported on this OS.'
Confusion and Misuse
However, the name of the exception,
NotImplementedError, can be misleading. Developers often misinterpret its purpose and use it in abstract methods or as a replacement for TODO comments. This misunderstanding has spread, leading to developers wrongly suggesting its use in situations where it doesn’t make sense. Also,
NotImplementedError inherited from
ScriptError , so it won’t be rescued:
Given the risks and potential confusion surrounding
NotImplementedError, it is crucial to consider alternative approaches. While there is no universal consensus, here are three options that can be considered:
Out of the existing Ruby exceptions, NoMethodError is the most appropriate for abstract methods. It clearly indicates that the method does not exist in the current context.
raise NoMethodError.new('method not implemented in this class')
Raise a RuntimeError
If the situations where you encounter this error are expected to be rare, you may choose to raise a RuntimeError with a specific message. This allows you to provide a custom error message while still adhering to Ruby’s exception hierarchy.
raise RuntimeError.new('method not implemented in this class')
Define a custom exception class
For more complex projects, it may be beneficial to define your own exception class and use it consistently throughout. For example, creating an
CustomMethodError class that inherits from
StandardError can provide clarity and consistency.
class CustomMethodError < StandardError
raise CustomMethodError.new('method not implemented in this class')
The misuse of
NotImplementedError in Ruby can lead to confusion and unexpected behavior. While the name may be appealing, it is essential to use this exception correctly in OS-dependent methods. For abstract methods or as a TODO replacement, alternative approaches like
RuntimeError, or a custom exception class are recommended.