Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>in Ruby you can reopen existing classes and add methods. That is, you can say:</p> <pre><code>class Foo def bob return "hello from bob" end end </code></pre> <p>these methods get stored somewhere in an internal dictionary (maybe an instance variable) of the <code>Foo</code>-class (which is just an instance of the <code>Class</code>-class and therefore <em>has</em> instance variables)</p> <p>But the suprising thing is, that you can also add methods to <em>instances</em> of existing objects</p> <pre><code>foo = Foo.new foo2 = Foo.new def foo.fred return "I am fred" end foo.fred #=&gt; "I am fred" foo2.fred #=&gt; NoMethodError </code></pre> <p>but <strong>Where is this method actually stored</strong>?</p> <p>Turns out Ruby creates a new class behind the scenes (sometimes called <em>singleton class</em>, <em>metaclass</em> or <em>eigenclass</em>) which gets inserted in the inheritance heirarchy <em>between</em> the <code>Foo</code>-class and its instance.</p> <p>So the inheritance relationship looks like that:</p> <pre><code>foo &lt; (eigenclass of foo) &lt; Foo &lt; Class </code></pre> <p>(if you say foo.superclass you will not see the singleton class)</p> <p>the <code>class &lt;&lt; X</code>-syntax is a way to get to this special class, so that you can manipulate it directly. The following code blocks are exactly equivalent:</p> <pre><code>def foo.bar return "xy" end # is exactly the same as class &lt;&lt; foo def bar return "xy" end end </code></pre> <p>So the similarity between <code>class Foo &lt; Bar</code> and <code>class &lt;&lt; Foo</code> is not accidental, there is inheritance going on in both.</p> <p>Think of <code>class &lt;&lt; X</code> as "open up the metaclass of X"</p> <p>The thing to remember in Ruby is that classes themselves are just objects. (Instances of the class <code>Class</code>) so if you say:</p> <pre><code>class Foo class &lt;&lt; self def k return "x" end end end </code></pre> <p>(<code>self</code> is bound to <code>Foo</code> in this code block) so <code>k</code> is an <em>instance method</em> of the eigenclass of <code>Foo</code>, which makes it a class method for <code>Foo</code></p> <p>all this is explained more clearly in the <a href="http://www.ruby-doc.org/docs/ProgrammingRuby/html/classes.html" rel="noreferrer">chapter about classes of the Pickaxe</a> (the web version does not contain the diagrams, unfortunately) and _whys <a href="http://ruby-metaprogramming.heroku.com/html/seeingMetaclassesClearly.html" rel="noreferrer">Seeing Metaclasses Clearly</a></p>
 

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