Well, this is the consensus that when an object is passed to Ruby, it is not type checked. Interfaces in Java and PHP are a way to confirm that an object matches a specific contract or "type" (so something could be Serializable , Authorizable , Sequential and whatever you want).
However, in Ruby there is no formalized concept of a contract, for which interfaces will play some significant role, since the correspondence of the interface is not checked in the method signatures. See, for example, Enumerable . When you mix it with your object, you are using functionality , not Declaring that your object is Enumerable . The only advantage that your object is Enumerable is that by defining each(&blk) you automatically get map , select and friends for free. You can perfectly have an object that implements all the methods provided by Enumerable , but does not mix in the module, and it will still work.
For example, for any method in Ruby that expects an I / O object, you can use something that has nothing to do with IO, and then it will explode with an error, or - if you correctly executed your IO stub - it will the work is fine even if your transferred object is not declared as "IO-ish".
The idea behind this is that the objects in Ruby did not actually glorify the hash tables with a label superimposed on them (which then have some additional tags that tell the interpreter or compiler that this object has an X interface, so it can be used in context Y), but a private person responding to messages. Therefore, if the object responds to a specific message, it completely fills out the contract, and if it does not respond to this message - well, then an error occurs.
Thus, the lack of interfaces is partially compensated by the presence of modules (which may contain the functionality you are accessing without any type of promises for the caller / consumer) and partly by the tradition of sending messages as opposed to typed dicts.
You should look at some of Jim Weirich's presentations, as he covers this topic in detail.