Ruby has three access levels. They are public
, private
and protected
.
Methods that follow the private
or protected
keywords are defined as such. Methods that come before these are implicitly public
methods.
A public method should describe the behavior of the object being created. These methods can be called from outside the scope of the created object.
class Cat
def initialize(name)
@name = name
end
def speak
puts "I'm #{@name} and I'm 2 years old"
end
...
end
new_cat = Cat.new("garfield")
#=> <Cat:0x2321868 @name="garfield">
new_cat.speak
#=> I'm garfield and I'm 2 years old
These methods are public ruby methods, they describe the behavior for initializing a new cat and the behavior of the speak method.
public
keyword is unnecessary, but can be used to escape private
or protected
def MyClass
def first_public_method
end
private
def private_method
end
public
def second_public_method
end
end
Private methods are not accessible from outside of the object. They are used internally by the object. Using the cat example again:
class Cat
def initialize(name)
@name = name
end
def speak
age = calculate_cat_age # here we call the private method
puts "I'm #{@name} and I'm #{age} years old"
end
private
def calculate_cat_age
2 * 3 - 4
end
end
my_cat = Cat.new("Bilbo")
my_cat.speak #=> I'm Bilbo and I'm 2 years old
my_cat.calculate_cat_age #=> NoMethodError: private method `calculate_cat_age' called for #<Cat:0x2321868 @name="Bilbo">
As you can see in the example above, the newly created Cat object has access to the calculate_cat_age
method internally. We assign the variable age
to the result of running the private calculate_cat_age
method which prints the name and age of the cat to the console.
When we try and call the calculate_cat_age
method from outside the my_cat
object, we receive a NoMethodError
because it's private. Get it?
Protected methods are very similar to private methods. They cannot be accessed outside the instance of object in the same way private methods can't be. However, using the self
ruby method, protected methods can be called within the context of an object of the same type.
class Cat
def initialize(name, age)
@name = name
@age = age
end
def speak
puts "I'm #{@name} and I'm #{@age} years old"
end
# this == method allows us to compare two objects own ages.
# if both Cat's have the same age they will be considered equal.
def ==(other)
self.own_age == other.own_age
end
protected
def own_age
self.age
end
end
cat1 = Cat.new("ricky", 2)
=> #<Cat:0x007fe2b8aa4a18 @name="ricky", @age=2>
cat2 = Cat.new("lucy", 4)
=> #<Cat:0x008gfb7aa6v67 @name="lucy", @age=4>
cat3 = Cat.new("felix", 2)
=> #<Cat:0x009frbaa8V76 @name="felix", @age=2>
You can see we've added an age parameter to the cat class and created three new cat objects with the name and age. We are going to call the own_age
protected method to compare the age's of our cat objects.
cat1 == cat2
=> false
cat1 == cat3
=> true
Look at that, we were able to retrieve cat1's age using the self.own_age
protected method and compare it against cat2's age by calling cat2.own_age
inside of cat1.