Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>I agree with Samir that it just sounds like duck typing. You don't need to care what 'type' an object really 'is' you only need bother with what an object can 'do'. This is true in both Ruby and Python.</p> <p>However if you really are checking the types of classes and you really do need to have a <code>Poodle</code> object optionally also be a <code>FurCoat</code> at runtime, then the way to do this in Ruby is to mixin a <code>FurCoat</code> module into the <code>Poodle</code> object, as follows:</p> <pre><code>class Poodle; end module FurCoat; def wear; end; end my_poodle = Poodle.new my_poodle.is_a?(Poodle) #=&gt; true my_poodle.is_a?(FurCoat) #=&gt; false my_poodle.wear #=&gt; NoMethodError # now we mix in the FurCoat module my_poodle.extend(FurCoat) # my_poodle is now also a FurCoat my_poodle.is_a?(Poodle) #=&gt; true (still) my_poodle.is_a?(FurCoat) #=&gt; true my_poodle.wear #=&gt; the wear method now works </code></pre> <p><strong>EDIT</strong> (due to your updated question):</p> <p>You still do not need to rewrite <code>Class</code> to achieve what you want, you just need to monkey-patch the <code>kind_of?</code> and <code>is_a?</code> (and potentially <code>instance_of?</code>) methods on Ruby's <code>Kernel</code> module. Since Ruby has open classes this is easily done:</p> <pre><code>class Module def obj_implements_interface?(obj) false end end module Kernel alias_method :orig_is_a?, :is_a? def is_a?(klass) orig_is_a?(klass) || klass.obj_implements_interface?(self) end end </code></pre> <p>And then define for each class (or module) what it means for an object to implement its interface:</p> <pre><code>class Dog def self.obj_implements_interface?(obj) obj.respond_to?(:bark) &amp;&amp; obj.respond_to?(:num_legs) &amp;&amp; obj.num_legs == 4 end end module FurCoat def self.obj_implements_interface?(obj) obj.respond_to?(:wear) end end </code></pre> <p>Now test it:</p> <pre><code>my_poodle = Poodle.new my_poodle.is_a?(FurCoat) #=&gt; false # now define a wear method on my_poodle def my_poodle.wear; end my_poodle.is_a?(FurCoat) #=&gt; true </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload