If I absolutely do not want the Hash-like object to have specific hash methods, I would wrap the object in my class and only expose the methods that I want it to have (your option b).
If I wanted it to retain its true hash behavior with some added behavior, I would add this behavior in the module to the hash object itself without changing the hash class class:
module SpecialHash def reindex
More often than not, one of these options will do the trick for me.
In general, I prefer to use modules to extend the behavior of a class instead of class inheritance, because I find it cleaner and easier. Creating a new class always gives me the feeling that I am adding a new βthingβ to my domain model. That's great, and exactly what you want to do in countless scenarios, but the Ruby mixin features give you a very nice alternative when you don't need to go that far.
The main time when I am creating a class is if there is some additional state in the object that I want to track. If my additions do not concern the extension of the state of an object, but simply extend its behavior, then I will almost always start by mixing this behavior with an existing instance of this class using a module.
Another answer to this question also brings up some other points to keep in mind: ruby inheritance vs mixins
source share