Public methods are the most crucial methods in Object Oriented Programming. They expose the external signature of your class to other classes. In a Car for example, you as a driver can do things like “opening the door”, “starting the ignition”, or “turn the steering wheel”.
However, under the hood (pun intended) there’s a plethora of supporting actions that are not accessible by the driver. Things like “send electicity to spark plug”, “engage disc brakes”, etc. are the hidden methods to driving a car and are not part of the public interface.
In PHP, for each method we need to explictly define if the method is public, protected or private.
In Ruby, methods are public by default. You don’t need to specify they’re public, it’s assumed unless otherwise marked that all methods in a class are part of the class’s signature.
No need to define any kind of
public anywhere in a Ruby class, it’s just implict that unless a method is defined otherwise - then it’s a public method:
class Car # Turn the steering wheel a certain direction def turn_wheel(direction) axel.turn(direction) end end
Using Private Methods
I’m going to go ahead and assume you’ve used some OOP in PHP in the past. One key concept is understanding “Private Methods”. This methods are used to organize logic internally inside of the Class.
The only difference between private methods and public methods, is that private methods are not accessible outside of the Object.
Private methods are not part of the Cat’s signature. A signature is just the available public methods on a particular object.
We have private method in Objects in Ruby as well. But they are defined a little differently:
class Cat def walk move_left_legs sleep 1 move_right_legs sleep 2 end def run move_left_legs move_right_legs def private def move_left_legs # use your imagination here ok? end def move_right_legs # yup, the right legs will move end end cat = Cat.new cat.stalk cat.run cat.move_left_legs => Cannot call 'move_left_legs'
Yup private methods are still a thing in Ruby.
In PHP, we have to explictly place the keyword
private in front of each method in a class:
However, Ruby’s take it on just requires you to set it once. Anything beneath the keyword
private becomes a private method:
private def moveLeftLegs # things happen here end def moveRightLegs # things happen here end
Protected methods are essentially a step between a private and a public method. It’s still private in that an outside class cannot use the protected methods, but it’s accessible to other inheriting classes a.k.a. children.
Take this generic Car class for example:
Pretty simple, the external user a.k.a. Driver is able to insert a
$key into the ignition and 2 interior methods will do the actual work. If the
checkKey method fails, then the car doesn’t start.
Alrightly let’s implement our
Car class in Ruby:
class Car def turn_ignition(key) # using a combination of a guard statement + implict paranthesis around an argument ignite_spark_plug if check_key key end protected def ignite_spark_plug car.ignite_spark_plug end private def check_key(key) key == slot end
Again, much less typing required for the same result.
What if we had a car that had one of those fancy keyless entries? Technically we wouldn’t have to have a
$key inserted into the car, but we want to extend the class for similar functionality:
Now, this is a sneak peak into extending classes in Ruby, but you’re ready for a little taste:
class KeylessCar < Car def turn_ignition # using a combination of a guard statement + implict paranthesis around an argument ignite_spark_plug if check_key end protected def ignite_spark_plug car.ignite_spark_plug end private def check_key key == slot end def super_secret_hash # Car developers, please don't do this 'supersecretstringshhhh' end
$this in Ruby?
So, I might have jumped ahead of myself in the last example. From inside of the Cat Class, we called the private method
move_right_legs, but we didn’t prepend
this. You’d expect to have to explictly tell Ruby to look for that method on the current Class.
Again, it’s optional you still can.
If you’d like to keep Ruby familiar as possible to what you already know. You can use the keyword
self to refer to the current Class. We can rewrite the
run method in our
Cat Class as such:
def run self.move_left_legs self.move_right_legs def
That’s totally valid as well. However, don’t be surprised to see a lack of
self in Classes by other Rubyists. After awhile you just get used to the implict nature of the language.