Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>Each of these examples fall into different cases.</p> <p>If you are writing methods that apply to all objects, then you open the <code>Object</code> class so all objects can access it. If you are writing methods that apply to all modules, then you open <code>Module</code>. Whenever you open a class to add methods, the methods should apply to <em>all instances of the class and nothing else</em>.</p> <p>Extending the <code>Kernel</code> module is different: people do this to add methods that should be available to every scope, but not really as methods to be explicitly called on an object, by making them private.</p> <p>When you are outside of any <code>class</code> or <code>module</code> statement, you are in the scope of the <code>main</code> object, and methods you define default to being private methods of <code>Object</code>. This is fine for small or simple programs, but you will eventually want to use proper modules as namespaces to organize your methods.</p> <p>As a final note on the subject, you always need to be sure that you really want methods you add to built-in classes and modules to be available to <em>everything in your application, including external inclusions</em> because they all share the built-ins.</p> <p>Now to apply this to answer your question. Because you are defining a method that creates accessors for class variables, you should put it in the class <code>Class</code> as it applies to all classes and nothing else. Finally, you will likely only use it in class definitions (within a <code>class</code> statement), so we should make it private:</p> <pre><code>class Class private def c_attr_accessor(name) # ... end end class User c_attr_accessor :class_variable_name # ... end </code></pre> <p>If you don't really need it in every class (maybe just a few), then create a "mixin module" to extend every class that needs this feature:</p> <pre><code>module ClassVariableAccessor private def c_attr_accessor(name) # ... end end class User extend ClassVariableAccessor c_attr_accessor :class_variable_name # ... end </code></pre> <p>Note that you are using <code>Object#extend</code> to add <code>c_attr_accessor</code> only to the object <code>User</code> (remember that classes are objects; you will hear that a lot if you are new to Ruby metaprogramming).</p> <p>There is another way to implement the last example, which works by explicitly extending its base class through the <code>Module#included(base_class)</code> "hook method" called whenever the module included, and the base class is passed to <code>base_class</code>:</p> <pre><code>module ClassVariableAccessor def included(base_class) base_class.extend ClassMethods end module ClassMethods def c_attr_accessor(name) # ... end end end class User include ClassVariableAccessor c_attr_accessor :class_variable_name # ... end </code></pre> <p>I recommend this last solution because it is the most general and uses a simple interface that should not need to be updated. I hope this is not too much!</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