Raising an error when at runtime you call a nonexistent method is native Ruby behavior, so why write methods that say "I don't exist"?
If doing this added in any build-time guarantees that you have to implement that method they'd be great, but as used they're just additional code for one to be aware of, slowing everyone down at code review and shifting the mental model away from the messages that are being passed.
If you need to document a duck type there probably are better ways to do it, and Ruby also provides inheritance hooks that could conceivably be used to detect the existence of methods at load time, but I've never seen that being used in the relatively numerous private code bases I've come across.
(Sorry for the numerous edits, the point became clearer after I posted this)
Well, first for documentation as you pointed.
Second because otherwise the error is a `NoMethodError` which inherits from `StandardError` hence may be casually rescued.
> Ruby also provides inheritance hooks that could conceivably be used to detect the existence of methods at load time
It's not every practical because the hook is called while the child class is opened, so no method is yet implemented into it. You'd need to collect all the child class and then check they implement all the necessary methods at a later point when you are done loading, which isn't a clearly defined point in a general Ruby program.
> Ruby also provides inheritance hooks that could conceivably be used to detect the existence of methods at load time
This misses numerous corner cases e.g. refinements, or the dynamic include/prepend of modules (which may even be generated anonymous modules). One may not write such code often in applications, but this happens routinely in the guts of many frameworks and libraries, and not just Rails.
Most attempts to introduce type checking or anything resembling it into Ruby run into the wall of "load time is run time".
___
[1] corollary: consider writing a respond_to? that returns false for the abstract method(s)
I and thusly our team uses `NotImplementedError` all over the place and I know I picked up that pattern from a rubygem somewhere along the line (predates copilot or generative code by years).
Even though I'm technically using it incorrectly, I don't want it to inherit `StandardError` and thus blows up. Because, I want it to blow up in the worst way possible. The handling engineer knows this is serious, and it if made it all the way to production, then our specs are lacking so bad that we need to have a discussion.
That's a feature to me.
someMethod:
self subclassResponsibility
I've suggested the name in the ruby bug tracker issue here:The C++/Java form of OOP is so conceptually divergent from Smalltalk-style OOP that it may be less confusing if we renamed it.
The difference (and that does not even need to involve Rails) is that these three - and thus compilation - happen at runtime, anytime, always.
The fact that a typical "main" file follows the "require first, then define modules and classes, then execute" creates a mental illusion of order; the fact that generally dependencies also follow this propagates that illusion across the board.
Therefore at the ruby source level you can only have runtime checks (and failure via exceptions), unless you bring in another static analysis tool such as Sorbet or RBS+Steep, which is an actual solution to enforce interface contracts without risking blowing up an app at runtime. That stays true even if there were a hypothetical "abstract" Ruby-level keyword. The only other solution without such tools is to have perfect (runtime) coverage via tests.
Note that mruby takes a fundamentally different approach here, and there's no require nor load.