Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>Looking at MRI code, every time you create a <code>Class</code> which in Ruby is object of type <code>Class</code>, automatically, ruby creates "metaclass" class for that new class, which is another <code>Class</code> object of singleton type.</p> <p>The C function calls (<code>class.c</code>) are: </p> <pre><code>rb_define_class rb_define_class_id rb_class_new(super); rb_make_metaclass(klass, RBASIC(super)-&gt;klass); </code></pre> <p>So, every time that you define a new class, Ruby will define another class with meta information.</p> <p>When you define a class method, I mean, <code>def self.method</code>, internally, ruby calls <code>rb_define_singleton_method</code>. You can check it doing the follow step:</p> <p>Create a ruby file <code>test.rb</code>:</p> <pre><code>class A def self.foo end end </code></pre> <p>And run the following command:</p> <pre><code>ruby --dump insns test.rb </code></pre> <p>You will have the following output:</p> <pre><code>== disasm: &lt;RubyVM::InstructionSequence:&lt;main&gt;@kcount.rb&gt;=============== 0000 trace 1 ( 70) 0002 putspecialobject 3 0004 putnil 0005 defineclass :A, &lt;class:A&gt;, 0 0009 leave == disasm: &lt;RubyVM::InstructionSequence:&lt;class:A&gt;@kcount.rb&gt;============ 0000 trace 2 ( 70) 0002 trace 1 ( 71) 0004 putspecialobject 1 0006 putself 0007 putobject :foo 0009 putiseq foo 0011 opt_send_simple &lt;callinfo!mid:core#define_singleton_method, argc:3, ARGS_SKIP&gt; 0013 trace 4 ( 73) 0015 leave ( 71) == disasm: &lt;RubyVM::InstructionSequence:foo@kcount.rb&gt;================== 0000 trace 8 ( 71) 0002 putnil 0003 trace 16 ( 72) 0005 leave </code></pre> <p>The <code>define_singleton_method</code> is mapped to the <code>rb_obj_define_method</code> C function (<code>object.c</code>), which do following calls:</p> <pre><code> rb_obj_define_method rb_singleton_class(obj) rb_mod_define_method </code></pre> <p>The function <code>rb_singleton_class</code> exposes the metaclass created when the class was defined, but it also creates a new metaclass for this metaclass. </p> <p>According the Ruby documentation for this function: "if a obj is a class, the returned singleton class also has its own singleton class in order to keep consistency of the inheritance structure of metaclasses".</p> <p>That is the reason why the number of class increases by 1 when you define a class method.</p> <p>The same effect happens if you change your code by:</p> <pre><code>class A end A.singleton_class </code></pre> <p>The <code>singleton_class</code> is mapped to <code>rb_obj_singleton_class</code> C function, which calls the <code>rb_singleton_class</code>.</p> <p>Even if you create a class method and call the <code>singleton_class</code> method, the number of created classes will not change, because all classes necessary to handle meta information is already created. Example:</p> <pre><code>class A def self.foo nil end end A.singleton_class </code></pre> <p>The code above will keep returning 3.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

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