Class Instance Variables
Part of the Object Oriented Programming section of Coddy's Ruby journey. Lesson 13 of 57.
A class is an object too, so it can have its own instance variables. @issued = 0 in the class body, where self is the class, belongs to the class and not to any instance. Class methods read and change it:
class Ticket
@issued = 0
def self.issue
@issued += 1
end
def self.issued
@issued
end
end
Ticket.issue
Ticket.issue
puts Ticket.issuedOutput:
2attr_accessor inside class << self generates a reader and setter on the class. Instances then reach the class's state through self.class, for example to count every object that new creates:
class Robot
@built = 0
class << self
attr_accessor :built
end
attr_reader :serial
def initialize
self.class.built += 1
@serial = self.class.built
end
end
a = Robot.new
b = Robot.new
puts "#{a.serial} #{b.serial} #{Robot.built}"Output:
1 2 2Ruby also has class variables, written @@name. A class variable is shared by the class and all of its instances, so instance methods can read it directly:
class Player
@@count = 0
def initialize
@@count += 1
end
def self.count
@@count
end
def others
@@count - 1
end
end
Player.new
last = Player.new
puts Player.count
puts last.othersOutput:
2
1A class variable is also shared with every subclass (a class built on another one, chapter 5), so a subclass that assigns it changes it for the parent too. A class instance variable stays separate per class, which is why most Ruby code prefers it:
class Base
@@kind = "base"
@label = "base"
class << self
attr_reader :label
end
def self.kind
@@kind
end
end
class Child < Base
@@kind = "child"
@label = "child"
end
puts Base.kind
puts Base.label
puts Child.labelOutput:
child
base
childChallenge
EasyComplete the class Ticket. Every new ticket gets the next number, starting at 1, from a counter kept in a class instance variable. Ticket.issued returns how many tickets have been issued since the last reset, and Ticket.reset sets the counter back to 0. to_s returns #3 Concert.
The supplied code reads lines. reset resets the counter; any other line is an event name, for which it creates a ticket and prints it. At the end it prints issued: 2.
Your code goes in ticket.rb. main.rb holds the supplied input/output code and cannot be edited.
Try it yourself
require_relative 'ticket'
# Supplied input/output code: keep it as it is
input = []
while (line = gets)
input << line.chomp
end
input.each do |line|
if line == "reset"
Ticket.reset
else
puts Ticket.new(line)
end
end
puts "issued: #{Ticket.issued}"
This lesson includes a short quiz. Start the lesson to answer it and track your progress.
All lessons in Object Oriented Programming
1Classes and Objects
Working With FilesDefining ClassesInstance VariablesMethods and selfto_s and inspectRecap - Library Card7Polymorphism and Duck Typing
PolymorphismDuck TypingAbstract Methodscase and ClassesRecap - Payment Methods2Accessors and Self
Readers and WritersCustom Settersself in MethodsIdentity and EqualityRecap - Contact List8Special Methods
Equality and hashOperator MethodsIndexing and AppendingCustom CollectionsRecap - Fractions11Project: Library Management
Books and MembersBorrowing Books3Class Methods and Variables
Class MethodsClass Instance VariablesConstantsFactory MethodsRecap - Coupon CodesPractice on your own: Online Ruby compiler