Programming Fundamentals (Part 6) - Classes
In our last several lessons, we learned some of the programming fundamentals that we'll need when writing applications. The next step is to combine these new concepts with real data from a SQL database - that's where the real fun begins!
But before we can get there, we need to briefly cover one more programming concept: Classes.
What is a Class?
A class is actually short for classification, which better describes its role in programming - the classification of a piece of data. Let's look at some of the data types we started with last week.
"Hello, world!"
"Tacos are delish."
"This is the way."
What type of things are these? Or, put another way, how would we classify each of these pieces of data? These are all strings. They come from the String class. Although they are all different, they are all from the String class - we say they are instances or objects of the String class.
Practically speaking, what that means is that they have some shared behavior. For example, although the content is different, each has a method .to_upcase
and knows what to do when that method is called:
"Hello, world!".upcase # "HELLO, WORLD!"
"Tacos are delish.".upcase # "TACOS ARE DELISH."
"This is the way.".upcase # "THIS IS THE WAY."
The same is true for the other data we learned about:
5
2
Both 5
and 2
are integers - instances of the Integer class. And the Integer class gives them both a shared method .to_f
which converts an integer into a different class: Float.
5.to_f # 5.0
2.to_f # 2.0
We can ask any object what kind of thing it is (i.e. what's its class):
"Hello, world!".class # String
5.class # Integer
5.to_f.class # Float
5.to_s.class # String
2.class # Integer
2.to_f.class # Float
2.to_s.class # String
More examples:
Here we have arrays, which, you can guess are instances of the Array class. And some of the shared methods that we've already explored include .sort
and .uniq
.
[4, 8, 15, 16, 23, 42]
["Rachel", "Monica", "Phoebe", "Ross", "Chandler", "Joey"]
And lastly, our hash data, which are instances of the Hash class.
{ "color" => "purple", "number" => 17, "computer" => "Apple" }
{ "name" => "Ben", "location" => "Chicago, IL", "status" => "Staying warm!" }
Code-along
Let's get some practice.
Go to this lesson's repository and open it in Gitpod. You'll notice a couple things are different than the previous Programming Fundamentals repository. First, there's some load time when it first opens in Gitpod - that's because we're installing several libraries and running a few files as setup for the following lessons. Second, the file structure in the left panel is much bigger than before. We're now in a complete Rails application repository which has A LOT of extra directories and files. We won't get into what that all means right now - we'll learn more about it as we go through the course. Don't worry - all in due time.
Let's look inside the code-along
directory and open the file 0-classes.rb
. Here's another difference - to run this file, we'll stay at our main directory in terminal which should read /workspace/ruby-and-sql
. From there, we'll use a command rails runner code-along/0-classes.rb
. This is similar to when we used ruby
and the file name, but now we're also loading in other libraries that we'll need. Again, don't worry too much about it now, just see if you can run the file without error (there shouldn't be any output).
Ok, in the file, let's create a few strings:
my_favorite_food = "ice cream"
puts my_favorite_food
your_favorite_food = "tacos"
puts your_favorite_food
When we run the file with rails runner code-along/0-classes.rb
we should see the output
ice cream
tacos
Let's check what their classes are by adding this code:
puts my_favorite_food.class
puts your_favorite_food.class
At this point, hopefully no surprise, the output is
String
String
These are instances of the String class. And because they're from the String class, they have all of the shared String methods like capitalize
and upcase
. How about we capitalize them:
puts my_favorite_food.capitalize
puts your_favorite_food.capitalize
And when you run the file, you'll see both strings are capitalized. Our complete output from running this file is now:
ice cream
tacos
String
String
Ice cream
Tacos
This might be interesting and clarify some of our earlier lessons, but how do we put this knowledge to use?
Custom Classes
Classes are kind of like factories or templates. Think of a car factory - it can build cars that are all similar but slightly different - each car has its own VIN (an identification number) and perhaps variations in color, but the cars all have shared behavior like being able to turn on and drive.
The built-in ruby classes are useful, but often we also need our own custom factories to build things that our application needs. For example, let's say we want to build virtual dogs and give them all some shared functionality. Go ahead and add the following code to our 0-classes.rb
file.
class Dog
def speak
puts "woof!"
end
end
This is a Dog
class with a method speak
. The code above is like building a factory - we're now able to create dogs, but we haven't yet. If you run the file (rails runner code-along/0-classes.rb
), nothing has changed. Now let's use our class to create a new dog instance:
lassie = Dog.new
lassie.speak
rover = Dog.new
rover.speak
We've built 2 different dogs that both can "speak" (i.e. output "woof!"). And the output you now see should be:
woof!
woof!
Interestingly, you didn't need to type puts
in our file. That's because the method itself already does that.
Defining a Class
When we define a class, we capitalize the name and use the singular - this is an important pattern. If you think again about a Car factory - a Car (singular) factory produces cars (plural). In the same way, our Dog (singular) class produces instances of dogs (plural). And it's capitalized to differentiate from all the variables that will inevitably be in our code (like lassie
and rover
). Don't forget about this pattern - if you do, expect to see some errors later on 😉.
That's about as far as we're going to take this idea for now. We could spend weeks on this topic, but the only reason it has any meaning at the moment is in light of our next topic - models.