SoFunction
Updated on 2025-04-07

ruby accessor concept

What is an accessor?

We have discussed the actual variables before, but have not discussed it too much. The actual variable of an object belongs to its attributes and is also the general difference between it and other objects from the same class. Reading and writing its attributes is important; doing so requires a method called attribute accessors. We will soon see that we do not always explicitly write the accessor method, but now let us understand all the details. The two types of accessors are write (writer) and reader).

ruby> class Fruit
    |   def set_kind(k)  # a writer
    |     @kind = k
    |   end
    |   def get_kind     # a reader
    |     @kind
    |   end
    | end
   nil
ruby> f1 = 
   #<Fruit:0xfd7e7c8c>
ruby> f1.set_kind("peach")  # use the writer
   "peach"
ruby> f1.get_kind           # use the reader
   "peach"
ruby> f1                    # inspect the object
   #<Fruit:0xfd7e7c8c @kind="peach">  


Simple enough; we can access information about the types of fruits we searched for. But our method name is a bit complaining. The following one is simpler and more convenient.

ruby> class Fruit
    |   def kind=(k)
    |     @kind = k
    |   end
    |   def kind
    |     @kind
    |   end
    | end
   nil
ruby> f2 = 
   #<Fruit:0xfd7e7c8c>
ruby>  = "banana"
   "banana"
ruby> 
   "banana"  


Inspect method

A small episode. You have noticed that when we try to observe an object directly, something like #<anObject: 0x83678> will appear. This is just a default behavior, and we can freely change it. All we have to do is add a method called inspect. It will change to a more explicit string describing the object, including some or all of the actual variables.

ruby> class Fruit
    |   def inspect
    |     "a fruit of the " + @kind + " variety"
    |   end
    | end
   nil
ruby> f2
   "a fruit of the banana variety"  


A related method is to_s (converted into a string), which is used when printing objects. Generally, you can think that inspect is a tool used when writing or debugging programs, while to_s is a method to beautify the output of the program. When displaying the results, inspect is always used. You can use the p method to simply obtain debugging information from the program.

# These two lines are equivalent:
p anObject
print , "\n"  


Easy way to generate an accessor

Because many real variables require access methods, Ruby provides abbreviation corresponding to standard methods.

Shortcut abbreviation
attr_reader :v        def v; @v; end  
attr_writer :v        def v=(value); @v=value; end  
attr_accessor :v      attr_reader :v; attr_writer :v  
attr_accessor :v, :w  attr_accessor :v; attr_accessor :w  

Let's use it to add "fresh" information. First, we automatically generate the read and write methods, and then we merge this new information into inspect:

ruby> class Fruit
    |   attr_accessor :condition
    |   def inspect
    |     "a " + @condition + @kind"
    |   end
    | end
   nil
ruby>  = "ripe"
   "ripe"
ruby> f2
   "a ripe banana"  


More interesting fruit

If no one eats our ripe fruits, maybe we should let them rot.

ruby> class Fruit
    |   def time_passes
    |     @condition = "rotting"
    |   end
    | end
   nil
ruby> f2
   "a ripe banana"
ruby> f2.time_passes
   "rotting"
ruby> f2
   "a rotting banana"  


But when we do this, a small problem is introduced. Now, what happens if we create a third fruit? Remember: the real variable will not exist before assignment.

ruby> f3 = 
ERR: failed to convert nil into String  


It's the inspect method that has a good reason to complain here. We've asked it to report the variety and status of the fruit, but f3 hasn't assigned any value yet. If we want, we can override the inspect method to use the define? method to test the actual variables and report them only when they exist, but maybe that's not very useful; because every fruit has a type and status. It seems we should determine its properties to some extent. This is exactly what we're going to discuss in the next section.