The family of attr_* methods is comprised of
attr_accessor. They are convenient shortcuts and defined in the Module class. Every class has access to these methods, since Module is the superclass of the Class class.
The basic idea
The idea of reader and writter methods is straightfoward. However, we want our attr_* methods to define these reader and writer methods for us. In order to implement this we will need to work with some metaprogramming techniques.
Before we turn to the attr_* methods we are going to look at the
define_method methods, which are often used in metaprogramming.
class_eval evaluates code in the context of the class it is called on.
define_method allows us to define instance methods for classes.
We can combine this knowledge by defining
break_code in the context of the Hacker class with
define_method defines an instance method in the receiver it will be an instance method for Hacker instances.
To access instance variables within an object we can use
Now let us apply these patterns for the attr_* methods. In order to retrieve an instance variable from an object we turn to
Similarly, for setting an instance variable of an object we turn to
instance_variable_set. You can see that we deliberately classify all of our attr_* methods as private, in line with the original methods.
attr_accessor can be implemented in terms of
attr_writer since it combines its functionality. The
* (splat) operator is used to correctly pass on a variable number of names.
So, in implementing
attr_accessor we have seen some metaprogramming techniques. We looked at
define_method to define our methods in the proper context.
instance_variable_set were used to retrieve and set internal state for an object. That was it, we have implemented the attr_* methods. If you want to review this code you can visit Understanding Ruby.