Defining a Virtual Attribute
Problem
You want to create accessor methods for an attribute that isn't directly backed by any instance variable: it's a calculated value derived from one or more different instance variables.
Solution
Define accessor methods for the attribute in terms of the instance variables that are actually used. There need not be any relationship between the names of the accessor methods and the names of the instance variables.
The following class exposes four accessor methods: degrees, degrees=, radians, and radians=. But it only stores one instance variable: @radians.
class Arc attr_accessor :radians def degrees @radians * 180 / Math::PI end def degrees=(degrees) @radians = degrees * Math::PI / 180 end end arc = Arc.new arc.degrees = 180 arc.radians # => 3.14159265358979 arc.radians = Math::PI / 2 arc.degrees # => 90.0
Discussion
Ruby accessor methods usually correspond to the names of the instance variables they access, but this is nothing more than a convention. Outside code has no way of knowing what your instance variables are called, or whether you have any at all, so you can create accessors for virtual attributes with no risk of outside code thinking they're backed by real instance variables.
See Also
- Recipe 2.9, "Converting Between Degrees and Radians"