Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p><code>class &lt;&lt; self</code> is more than just a way of declaring class methods (though it can be used that way). Probably you've seen some usage like:</p> <pre><code>class Foo class &lt;&lt; self def a print "I could also have been defined as def Foo.a." end end end </code></pre> <p>This works, and is equivalent to <code>def Foo.a</code>, but the way it works is a little subtle. The secret is that <code>self</code>, in that context, refers to the object <code>Foo</code>, whose class is a unique, anonymous subclass of <code>Class</code>. This subclass is called <code>Foo</code>'s <em>eigenclass</em>. So <code>def a</code> creates a new method called <code>a</code> in <code>Foo</code>'s eigenclass, accessible by the normal method call syntax: <code>Foo.a</code>.</p> <p>Now let's look at a different example:</p> <pre><code>str = "abc" other_str = "def" class &lt;&lt; str def frob return self + "d" end end print str.frob # =&gt; "abcd" print other_str.frob # =&gt; raises an exception, 'frob' is not defined on other_str </code></pre> <p>This example is the same as the last one, though it may be hard to tell at first. <code>frob</code> is defined, not on the <code>String</code> class, but on the eigenclass of <code>str</code>, a unique anonymous subclass of <code>String</code>. So <code>str</code> has a <code>frob</code> method, but instances of <code>String</code> in general do not. We could also have overridden methods of String (very useful in certain tricky testing scenarios).</p> <p>Now we're equipped to understand your original example. Inside <code>Foo</code>'s initialize method, <code>self</code> refers not to the class <code>Foo</code>, but to some particular <em>instance</em> of <code>Foo</code>. Its eigenclass is a subclass of <code>Foo</code>, but it is not <code>Foo</code>; it couldn't be, or else the trick we saw in the second example couldn't work. So to continue your example:</p> <pre><code>f1 = Foo.new(:weasels) f2 = Foo.new(:monkeys) f1.weasels = 4 # Fine f2.monkeys = 5 # Also ok print(f1.monkeys) # Doesn't work, f1 doesn't have a 'monkeys' method. </code></pre> <p>Hope this helps.</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