What’s the purpose of @ and attribute accessors in Ruby? The key concept here is survival. Ok, that sounds a little dramatic, but access to and longevity of an instance variable or its attributes is crucial if we want to access and manipulate them outside of their native block of code.
Take the creation of a coffee class that takes the attributes of size and type defined as follows,
class Coffee
def initialize(size, type)
end
coffee = Coffee.new(:medium, :cappuccino)
puts coffee
That at least tells us there’s a card there, but, it hasn’t stored the rank and the suit values. You might be thinking, “cool, well, I can just grab one of those attributes with the following code”,
puts coffee.size
But remember, survival.
Outside that “end” block, those attributes can’t be stored or accessed. That’s where you need to @them. Even if it’s not your style.
So,
class Coffee
def initialize(size, type)
@type = type
@size = size
end
coffee = Coffee.new(:medium, :cappuccino)
puts coffee.type
Now the attributes can be stored in memory. These are called “instance variables” and they survive as long as the card is around. But, we still need to access those attributes outside the block of code. One way of doing this is to create a method for each,
class Coffee
def initialize(size, type)
@type = type
@size = size
end
def size
@size
end
def type
@type
end
end
coffee = Coffee.new(:medium, :cappucino)
puts coffee.type
Try it out in the terminal with your own class and attributes. We survived! What more is there? Well, shorthand survival. Because, ain’t nobody got time for that.
In Ruby using an attribute reader, attr_reader, will do exactly the same thing as above, allow you to access and output the method.
class Coffee
attr_reader :size, :type
def initialize(size, type)
@size = size
@type=type
end
coffee = Coffee.new(:medium, :cappuccino)
puts coffee.type
puts coffee.size
end
It works! It won’t, however, allow you to manipulate or change it. That’s what the attr_writer is for.
class Coffee
attr_reader :size, :type
attr_writer :size, :type
def initialize(size, type)
@size = size
@type=type
end
coffee = Coffee.new(:medium, :cappuccino)
coffee.type = ‘latte’
puts coffee.type
puts coffee.size
end
And, even shorter again, attr_accessor, because we’re probably going to use both, right?
class Coffee
attr_accessor :size, :type
def initialize(size, type)
@size = size
@type=type
end
coffee = Coffee.new(:medium, :cappuccino)
coffee.type = ‘latte’
puts coffee.type
puts coffee.size
end
Finally, rather than just calling the attributes, we can add an output method that will output the coffee itself.
Finally, rather than just calling the attributes, we can add an output method that will output the coffee itself.
class Coffee
attr_accessor :size, :type
def initialize(size, type)
@size = size
@type=type
end
def output_coffee
puts “A #{@size} sized #{@type}”
end
puts “A #{@size} sized #{@type}”
end
coffee = Coffee.new(:medium, :cappuccino)
coffee.type = ‘latte’
coffee.output_coffee
end
And you should be left with a “medium sized latte”. Yum.
coffee.output_coffee
end
And you should be left with a “medium sized latte”. Yum.
So, did you survive?