{"id":7041,"date":"2014-05-17T00:24:11","date_gmt":"2014-05-17T00:24:11","guid":{"rendered":"https:\/\/unknownerror.org\/index.php\/2014\/05\/17\/scope-of-class-variable-collection-of-common-programming-errors\/"},"modified":"2014-05-17T00:24:11","modified_gmt":"2014-05-17T00:24:11","slug":"scope-of-class-variable-collection-of-common-programming-errors","status":"publish","type":"post","link":"https:\/\/unknownerror.org\/index.php\/2014\/05\/17\/scope-of-class-variable-collection-of-common-programming-errors\/","title":{"rendered":"Scope of class variable-Collection of common programming errors"},"content":{"rendered":"<p>My notes below are taken from Metaprogramming Ruby (by Paolo Perrotta), which I happened to be reading right now just as I came across your question. I hope that these excerpts (page numbers will be in parentheses) and my explanation are helpful to you.<\/p>\n<p>Keep in mind that <em>class variables<\/em> are different from <em>class instance variables<\/em>.<\/p>\n<blockquote>\n<p>A Class instance variable belongs to an object of class <code>Class<\/code>, and is accessible only by the class itself &#8211; not by an instance or by a subclass. (106)<\/p>\n<\/blockquote>\n<p>The <em>class variable<\/em>, on the other hand, belongs to class <em>hierarchies<\/em>. That means that it belongs to any class as well as all descendants of that class.<\/p>\n<p>Here is an example from the author:<\/p>\n<pre><code>@@v = 1\n\nclass MyClass\n  @@v = 2\nend\n\n@@v    # =&gt; 2\n<\/code><\/pre>\n<blockquote>\n<p>You get this result because class variables don&#8217;t really belong to classes &#8211; they belong to class <em>hierarchies<\/em>. Since @@v is defined in the context of <code>main<\/code>, it belongs to <code>main's<\/code> class <code>Object<\/code>&#8230; and to all the descendants of <code>Object<\/code>. <code>MyClass<\/code> inherits from <code>Object<\/code>, so it ends up sharing the same class variable. (107)<\/p>\n<\/blockquote>\n<p>But also, since your specific question has to do not only with classes but also with modules:<\/p>\n<blockquote>\n<p>When you include a module in a class, Ruby will create an anonymous class that wraps the module and inserts the anonymous class in the chain, just above the including class itself. (26)<\/p>\n<\/blockquote>\n<p>So, as you look at <code>B.ancestors<\/code>, you will see:<\/p>\n<pre><code>=&gt; [B, A, Object, Kernel, BasicObject]\n<\/code><\/pre>\n<p>Similarly, for <code>C.ancestors<\/code>, you will see:<\/p>\n<pre><code>=&gt; [C, A, Object, Kernel, BasicObject]\n<\/code><\/pre>\n<p>If we keep in mind that class variables belong to class hierarchies, then the class variable <code>@@foo<\/code>, as soon as it is defined in <code>Module A<\/code> (and so, the anonymous class just above <code>B<\/code> that is created as soon as <code>B<\/code> includes <code>A<\/code>), will belong to <code>B<\/code> (and also to <code>C<\/code>, since it includes <code>A<\/code>).<\/p>\n<p>To put it simply:<\/p>\n<ol>\n<li>When <code>@@foo<\/code> was only defined in <code>B<\/code> and in <code>C<\/code> (but not in <code>A<\/code>), then <code>B<\/code> had a class variable <code>@@foo<\/code> that was different than the class variable <code>@@foo<\/code> in <code>C<\/code>. This is because the class variables are only accessible to that class and to all descendants. But <code>B<\/code> and <code>C<\/code> are related through their ancestor <code>A<\/code>, and not through their descendants.<\/li>\n<li>As soon as <code>@@foo<\/code> was defined in <code>A<\/code>, that class variable became inherited by all descendants of <code>A<\/code> &#8211; that is, <code>B<\/code> and <code>C<\/code>. From here on out, the reference to <code>@@foo<\/code> in class <code>B<\/code> is really referencing the class variable that belongs to <code>A<\/code>. The original <code>@@foo<\/code> which was defined in <code>B<\/code> has been overwritten replaced (taken over by its ancestor). The same has happened to the <code>@@foo<\/code> in <code>C<\/code>. <code>B<\/code> and <code>C<\/code> can both write to and read from the same class variable <code>@@foo<\/code>, since it belongs to their common ancestor, <code>A<\/code>.<\/li>\n<\/ol>\n<p>At this point, anyone of <code>A<\/code>, <code>B<\/code>, or <code>C<\/code> can all modify <code>@@foo<\/code>. For example:<\/p>\n<pre><code>class B\n  p @@foo  # =&gt; 3\n  @@foo = 1\nend\n\nmodule A\n  p @@foo  # =&gt; 1\nend\n<\/code><\/pre>\n","protected":false},"excerpt":{"rendered":"<p>My notes below are taken from Metaprogramming Ruby (by Paolo Perrotta), which I happened to be reading right now just as I came across your question. I hope that these excerpts (page numbers will be in parentheses) and my explanation are helpful to you. Keep in mind that class variables are different from class instance [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-7041","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/posts\/7041","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/comments?post=7041"}],"version-history":[{"count":0,"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/posts\/7041\/revisions"}],"wp:attachment":[{"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/media?parent=7041"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/categories?post=7041"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/tags?post=7041"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}