Protected Methods
Part of the Object Oriented Programming section of Coddy's Ruby journey. Lesson 18 of 57.
A protected method sits between public and private. Outside code cannot call it, but any object of the same class can call it on another one. That lets two objects compare data they do not show to the rest of the program:
class Account
def initialize(owner, balance)
@owner = owner
@balance = balance
end
def richer_than?(other)
balance > other.balance
end
protected
def balance
@balance
end
end
ada = Account.new("Ada", 500)
bo = Account.new("Bo", 300)
puts ada.richer_than?(bo)
begin
ada.balance
rescue NoMethodError => e
puts e.message
endOutput:
true
protected method `balance' called for an instance of AccountThe difference from private shows when the receiver is another object. other.balance works for a protected method and fails for a private one:
class Sample
def initialize(n)
@n = n
end
def compare_protected(other)
other.guarded + guarded
end
def compare_private(other)
other.hidden + hidden
rescue NoMethodError
"private refused other.hidden"
end
protected
def guarded
@n
end
private
def hidden
@n
end
end
a = Sample.new(1)
b = Sample.new(2)
puts a.compare_protected(b)
puts a.compare_private(b)Output:
3
private refused other.hiddenprotected also works with attr_reader, the usual way to share a value only among objects of one class, for example to decide which of two objects wins:
class Player
attr_reader :name
def initialize(name, rating)
@name = name
@rating = rating
end
def stronger?(other)
rating > other.rating
end
protected
attr_reader :rating
end
a = Player.new("Ada", 1200)
b = Player.new("Bo", 1100)
puts a.stronger?(b)
puts [a, b].select { |pl| pl.stronger?(b) }.map(&:name).inspectOutput:
true
["Ada"]Choose the narrowest level that works. public is for the class's interface, protected for data that objects of the class compare with each other, and private for everything else:
public # anyone: order.total
protected # objects of the class: other.balance inside Account
private # only the object itself: subtotal, self.subtotalChallenge
EasyComplete the class Account. The balance is readable only by other accounts: make its reader protected. richer_than?(other) compares balances, transfer_to(other, amount) moves money to another account through the other account's protected method receive(amount) and returns true, or returns false when the balance is too low. to_s returns only the owner's name.
The supplied code reads the two owners and balances, then transfer a b 50 commands, printing ok or refused. It then prints Ada is richer (or Bo is richer, or equal) and finally tries to read balance from outside, printing balance is protected when Ruby refuses.
Your code goes in account.rb. main.rb holds the supplied input/output code and cannot be edited.
Try it yourself
require_relative 'account'
# Supplied input/output code: keep it as it is
input = []
while (line = gets)
input << line.chomp
end
accounts = input[0..1].map do |line|
owner, balance = line.split
Account.new(owner, balance.to_i)
end
a, b = accounts
input.drop(2).each do |line|
_, from, to, amount = line.split
source = from == "a" ? a : b
target = to == "a" ? a : b
puts source.transfer_to(target, amount.to_i) ? "ok" : "refused"
end
if a.richer_than?(b) then puts "#{a} is richer"
elsif b.richer_than?(a) then puts "#{b} is richer"
else puts "equal"
end
begin
a.balance
puts "balance is public"
rescue NoMethodError
puts "balance is protected"
end
This lesson includes a short quiz. Start the lesson to answer it and track your progress.
All lessons in Object Oriented Programming
1Classes and Objects
Working With FilesDefining ClassesInstance VariablesMethods and selfto_s and inspectRecap - Library Card7Polymorphism and Duck Typing
PolymorphismDuck TypingAbstract Methodscase and ClassesRecap - Payment Methods2Accessors and Self
Readers and WritersCustom Settersself in MethodsIdentity and EqualityRecap - Contact List8Special Methods
Equality and hashOperator MethodsIndexing and AppendingCustom CollectionsRecap - Fractions11Project: Library Management
Books and MembersBorrowing Books3Class Methods and Variables
Class MethodsClass Instance VariablesConstantsFactory MethodsRecap - Coupon CodesPractice on your own: Online Ruby compiler