- Define a class variable.
- Define a class method.
- Understand why and when to use class variables and methods.
- Understand the scope of class variables and class methods.
All objects are bundles of data and logic––or attributes and behavior. We understand this to be true of instances of a class. Each instance contains attributes or properties as well as methods that can enact behaviors.
For example, let's say we have a class, Album
. Every individual album instance should have a release date attribute. To accomplish this, we'll define an instance variable, @release_date
and an instance method #release_date
that exposes or reveals that variable.
class Album
def release_date=(date)
@release_date = date
end
def release_date
@release_date
end
end
Here we have an instance variable, @release_date
, which can be set equal to a value using the release_date=()
method, a setter method. Then, we have a getter method release_date
that returns the value of @release_date
. Now, we can execute the following:
album = Album.new
album.release_date = 1991
album.release_date
# => 1991
What you might not know, however, is that the Album
class itself is also an object. If our definition of an object is a bundle of code that contains attributes and behaviors, then the entire Album
class itself absolutely qualifies.
The Album
class can have its own variables and methods. We call these class variables and class methods.
Let's say you wanted to keep a counter for how many albums you had in your music collection. That way, you can brag to your friends about what a music aficionado you are. The current code in our Album
class has no way to keep such a count. Looks like we will have to write some code to accommodate this new feature of our program.
When it comes to adding new features or functionalities to our code, we start out by asking a question: whose responsibility is it to enact this behavior or functionality?
Right now, our program is pretty simple. We have an Album
class and we have album instances. So, is it the responsibility of an individual album to keep a count of all of the other albums? Or is it the responsibility of the Album
class, which actually produces the individual albums, to keep a running count? I think we can agree that it isn't the job of the individual albums, but the job of the Album
class to keep a count of all of the instances it produces.
Now that we've decided whose job it is to enact the "keep a count of all albums" behavior, we can talk about how we enact that behavior.
We do so with the use of class variables and methods. Our goal is to be able to ask the Album
class: "how many albums have you produced?" When we ask an object to tell us something about itself, we use methods. It would be great if we could do something like:
Album.count
and return the number of existing albums. Let's build out this capability now.
An instance variable is responsible for holding information regarding an instance of a class and is accessible only to that instance of the class. A class variable is accessible to the entire class––it has class scope. A class method is a method that is called on the class itself, not on the instances of that class. Class variables store information regarding the class as a whole and class methods enact behaviors that belong to the whole class, not just to individual instances of that class.
A class variable looks like this: @@variable_name
. Just like an instance or a local variable, you can set it equal to any type of data.
Let's create a class variable, @@album_count
and set it equal to 0
.
class Album
@@album_count = 0
def release_date=(date)
@release_date = date
end
def release_date
@release_date
end
end
Great, now we have a class variable to store our count of albums in. We can't yet access that variable from outside of our class though. How can we expose the contents of that variable? With a class method.
A class method is defined like this:
def self.class_method_name
# some code
end
Here, the self
keyword refers to the entire class itself, not to an instance of the class. In this case, we are inside the class only, not inside an instance method of that class. So, we are in the class scope, not the instance scope.
Let's define a class method .count
that returns the current count of albums.
class Album
@@album_count = 0
def self.count
@@album_count
end
end
Great, now if we call:
Album.count
It will return 0
.
Currently, however, our @@album_count
is stuck at 0
. When and how should we increment it? The count of albums should go up as soon as a new album is created, or initialized. We can hook into this moment in time in our #initialize
method.
class Album
@@album_count = 0
def initialize
@@album_count += 1
end
def self.count
@@album_count
end
end
Here we are using the @@album_count
class variable, inside of our #initialize
method, which is an instance method. We are saying: when a new album is created, access the @@album_count
class variable and increment its value by 1.
We can access our class variables anywhere in our class: in both class and instance methods.
Now our code should behave in the following manner:
Album.new
Album.new
Album.new
Album.count
# => 3
View Class Variables and Class Methods on Learn.co and start learning to code for free.