Constantize to the Rescue!
I recently came across an interesting problem. I had a couple of classes Teacher
and Student
. Both classes had a method called .login
that brings you to their respective login screens. While it may be inefficient, the user type is inputted by the user through a gets
method.
user = gets.strip # where user equals "Teacher" or "Student"
We either want to call Teacher.login
or Student.login
based on whichever option is submitted through the input. We can do this with an if/elsif statement like this:
if user == "Teacher"
Teacher.login
elsif user == "Student"
Student.login
end
That can get pretty inefficient with the more user types added and can result in an extraneous amount of code.
So, I figured it would be most efficient if we tried to execute something along the lines of user.login
, where user
is the class name we’re trying to access. While it looks like it should work, it doesn’t. We get an error —
undefined method `login’ for “Student”:String
Being that I was only recently introduced to Ruby at the time, I was perplexed as to why I kept receiving this error.
After some research, I discovered object types in Ruby. There are a bunch of different object types such as a string, integer, boolean, etc. So what type of object is Student
or Teacher
? To find the target object type that we need user to be, I ran Student.class
and that returned Class
. So, if we want user.login
to work, we need to get user to be a Class object type and not a String.
Ruby’s constantize
method provides a really efficient way to solve the problem at hand. user.constantize
turns user
into an object type of Class and thus the final code works:
user.constantize.login
This shortens our original code significantly, especially when we are operating with more that two user types.