Now we are ready to create our very own Address class. Let’s start simple. Let’s start with an address that only contains the “street” field.
This is how you define a class:
class Address
def initialize(street)
@street = street
end
end
Let’s go through this:
- The
class
keyword defines a class. - By defining a method inside this class, we are associating it with this class.
- The
initialize
method is what actually constructs the data structure. Every class must contain an initialize method. @street
is an object variable. Similar to the keys of a hash. The @ sign distinguishes @street as an object variable. Every time you create an object of the class Address, this object will contain a @street variable.
Let’s use this class to create an address object.
address = Address.new("23 St George St.")
That’s it. address
is now an object of the class Address
.
Reading the data in an object¶
Suppose that we want to read the data in the address object. To do this, we need to write a method that returns this data:
class Address
def initialize(street)
@street = street
end
# Just return @street
def street
@street
end
end
Now the method Address#street
lets you read the street of the address. In irb:
>> address.street
=> "23 St George St."
A property of an object, which is visible outside, is called an attribute. In this case, street is is an attribute. In particular, it is a readable attribute. Because this kind of attribute is very common, Ruby offers you a shortcut through the attr_reader keyword:
class Address
attr_reader :self
def initialize(street)
@street = street
end
end
Changing the data in an object¶
We can also define a method to change the data in an object.
class Address
attr_reader :street
def initialize(street)
@street = street
end
def street=(street)
@street = street
end
end
Ruby is pretty smart in its use of the street=
method:
address.street = "45 Main St."
Notice that you can put spaces betten street
and =
. Now that we can change the address data, we can simplify the initialize
method, and have it simply default the street to the empty string "".
class Address
attr_reader :street
def initialize
@street = ""
end
def street=(street)
@street = street
end
end
address = Address.new
address.street = "23 St George St."
This might not seem like much of a simplification, but when we add the city, state and zip fields, and more methods this will make the class definition a bit simpler.
Now, street is also a writable attribute. As before, you can declare it as such with attr_writer:
class Address
attr_reader :street
attr_writer :street
def initialize
@street = ""
end
end
Accessing data¶
Very often, you have attributes that are both readable and writable attributes. Ruby lets you lump these together with attr_accessor. I guess these would be called “accessible attributes”, but I have never seen them be called that.
class Address
attr_accessor :street
def initialize
@street = ""
end
end
With this knowledge, it is now easy to define the entire addressbook structure. As it turns out, attr_accessor and friends all accept multiple arguments.
class Address
attr_accessor :street, :city, :state, :zip
def initialize
@street = @city = @state = @zip = ""
end
end