Each of these examples relates to different cases.
If you write methods that apply to all objects, you open the Object class so that all objects can access it. If you write methods that apply to all modules, then you open Module . Whenever you open a class to add methods, the methods should be applied to all instances of the class and nothing else.
The Kernel extension is different: people do this by adding methods that should be available for each scope, but not so that the methods are explicitly called for the object, making them private.
If you are outside of any class or Module operator, you fall into the scope of the main object and the methods that you define by default as private methods of Object . This is good for small or simple programs, but ultimately you will want to use the appropriate modules as namespaces to organize your methods.
As a final note on this subject, you should always be sure that you really want the methods that you add to the built-in classes and modules to be accessible to everything in your application, including external inclusions, since they all share the built-in classes and modules , other.
Now apply this to answer your question. Since you are defining a method that creates accessors for class variables, you must put it in the class class , as it applies to all classes and nothing more. Finally, you are most likely to use it only in class definitions (in the class statement), so we must make it private:
class Class private def c_attr_accessor(name) # ... end end class User c_attr_accessor :class_variable_name
If you really do not need this in every class (maybe several), then create a “mixin module” to extend each class that needs this function:
module ClassVariableAccessor private def c_attr_accessor(name) # ... end end class User extend ClassVariableAccessor c_attr_accessor :class_variable_name
Note that you use Object#extend to add c_attr_accessor only to the User object (remember that classes are objects, you will hear this a lot if you are new to Ruby metaprogramming).
There is another way to implement the last example, which works by explicitly extending its base class using the "" Module#included(base_class) , called whenever the module is turned on, and the base class is passed to base_class :
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
I recommend this last solution because it is the most general and uses a simple interface that does not need to be updated. Hope this is not too much!