Ruby Method Visibility
Methods are public by default, so code outside an object can call them freely. The private and protected settings set limits on who may call a method.
Private answers only inside
secret_word is private, so the outside check answers false. The public welcome method still uses it from inside.
class Greeter
def welcome
puts secret_word
end
private
def secret_word
"sunshine"
end
end
greeter = Greeter.new
puts greeter.respond_to?(:secret_word)
greeter.welcome
puts greeter.respond_to?(:welcome)send reaches a private method
The outside check still answers false for the private method. send names the method with a symbol and calls it anyway.
class Greeter
def welcome
puts secret_word
end
private
def secret_word
"sunshine"
end
end
greeter = Greeter.new
puts greeter.respond_to?(:secret_word)
puts greeter.send(:secret_word)A rescue prints only the error class
Calling the private method from outside raises an error. The rescue prints the class of that error and nothing else.
class Greeter
private
def secret_word
"sunshine"
end
end
greeter = Greeter.new
begin
greeter.secret_word
rescue => e
puts e.class
endProtected lets classmates ask
amount is protected, so the outside check answers false. A wallet can still read the amount of another wallet inside richer_than?.
class Wallet
def initialize(amount)
@amount = amount
end
def richer_than?(other)
@amount > other.amount
end
protected
def amount
@amount
end
end
first = Wallet.new(50)
second = Wallet.new(30)
puts first.richer_than?(second)
puts first.respond_to?(:amount)Example
class Diary
def initialize(secret)
@secret = secret
end
def read_entry
puts plain_secret
end
private
def plain_secret
@secret
end
end
diary = Diary.new("meet at noon")
puts diary.respond_to?(:plain_secret)
diary.read_entry
puts diary.send(:plain_secret)Key points
- A public method can be called from anywhere.
- The word private makes every method below it private in that class.
- A private method runs only from inside its own object.
- respond_to? answers false for a private method from outside.
- send reaches a private method anyway, so it is a limit, not a lock.
- A protected method can be called on another object of the same class.
In this example, plain_secret is private and the outside check answers false. read_entry is public and prints the secret from inside the object. send reaches the private method and returns the same secret.
Note
The verdict lines in this lesson are the proof, since the full error text is never printed here.
Try it Yourself
Edit the code, then press Run.
Running is simulated
Exercise
What does respond_to? answer for a private method when asked from outside the object?