Hacker News new | ask | show | jobs
by ngcazz 803 days ago
I have always been unconvinced of the value of doing Java-style abstract classes to assert a certain API in Ruby considering it's duck-typed.

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)

2 comments

> 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"?

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.

There's a very simple reason. Writing explicit abstract methods ensures that both the parent and its subclasses can still use "method_missing" without having to special-case the landmine¹.

> 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)