主要观点:Ruby 的 NotImplementedError
异常常被用作抽象类中应被子类实现的方法的占位符,但这并非该异常类的预期用途。
关键信息:
- 常见误用示例:在
BaseSetting
类中,to_html
方法在未被子类实现时抛出NotImplementedError
,Text
子类实现了该方法,而Number
子类忘记实现。 - 实际用途:当当前平台不支持某功能时会抛出该异常,如 JRuby 不支持
fork
时调用Process.fork
会抛出该异常。 - 避免使用的原因:其语义可能导致误解,如在
convert_to_html
方法中,rescue => e
不能捕获NotImplementedError
,因为它继承自ScriptError
而非StandardError
。 - Python 的
NotImplementedError
:在 Python 中该异常实际用于抽象方法,与 Ruby 不同。 替代方法:
- 提供默认实现:在基类中提供默认的
to_html
方法实现,避免抛出异常。 - 明确抛出带消息:在抽象方法中明确抛出带有错误消息的异常,告知需要做什么来修复。
- 创建自定义异常:定义继承自
StandardError
的自定义异常并抛出。 - 抛出
NoMethodError
:更接近表达类未响应某个方法的意思。 - 编写测试:通过测试确保子类实现了特定方法,而不是依赖抽象方法抛出异常。
- Sorbet:在复杂代码库中可使用 Sorbet 进行类型检查,它会告知哪些子类需要实现抽象方法。
重要细节:
- 提供默认实现:在基类中提供默认的
- Ruby 的异常类继承关系:
NotImplementedError
继承自ScriptError
,后者继承自Exception
,而StandardError
不在此继承链中。 - 不同框架的示例:如 ActiveRecord 从模型名推断表名,Hanami 框架中处理抽象方法的方式。
- 相关更新:Michael Kohl 建议使用
SubclassResponsibility
作为抽象方法的异常名;Sorbet 内部在定义抽象方法时使用NotImplementedError
。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。