Private Methods
Part of the Object Oriented Programming section of Coddy's Ruby journey. Lesson 17 of 57.
Encapsulation means an object hides how it works and offers a small set of public methods. Methods are public by default. Every method defined after the word private in a class body is private: the object's own methods can call it, outside code cannot:
class Order
def initialize(price, quantity)
@price = price
@quantity = quantity
end
def total
subtotal + shipping
end
private
def subtotal
@price * @quantity
end
def shipping
subtotal >= 50 ? 0 : 5
end
end
order = Order.new(10, 3)
puts order.total
begin
order.subtotal
rescue NoMethodError => e
puts e.message
endOutput:
35
private method `subtotal' called for an instance of OrderInside the class, a private method is called without a receiver or with self.. Calling it on another object, even one of the same class, is refused:
class Coin
def initialize(cents)
@cents = cents
end
def describe
"#{self.label} / #{label}"
end
def same_as?(other)
other.label == label
end
private
def label
"#{@cents}c"
end
end
a = Coin.new(5)
puts a.describe
begin
a.same_as?(Coin.new(5))
rescue NoMethodError => e
puts e.message
endOutput:
5c / 5c
private method `label' called for an instance of Coinprivate can also take a method name, and def returns the method's name, so private def helper makes a single method private right where it is defined. The methods above and around it stay public:
class Greeter
def greet(name)
"#{salutation}, #{name}!"
end
private def salutation
"Hello"
end
def wave
"*waves*"
end
end
g = Greeter.new
puts g.greet("Ada")
puts g.wave
p Greeter.private_instance_methods(false)Output:
Hello, Ada!
*waves*
[:salutation]Keep helpers private. The public methods are the promise a class makes to the rest of the program; private ones can be renamed or removed later without breaking any caller:
class Invoice
def total # public: callers rely on it
net + tax
end
private # free to change later
def net
...
end
def tax
...
end
endChallenge
EasyComplete the class Order. Its only public method besides initialize is receipt, which returns 3 x 12.50 = 37.50, tax 7.50, total 45.00. The private methods subtotal (price times quantity), tax (20% of the subtotal) and total compute the numbers.
The supplied code reads orders as quantity price lines and prints each receipt. Then it tries to call tax from outside and prints tax is private when Ruby refuses.
Your code goes in order.rb. main.rb holds the supplied input/output code and cannot be edited.
Try it yourself
require_relative 'order'
# Supplied input/output code: keep it as it is
input = []
while (line = gets)
input << line.chomp
end
orders = input.map do |line|
quantity, price = line.split
Order.new(quantity.to_i, price.to_f)
end
orders.each { |o| puts o.receipt }
begin
orders[0].tax
puts "tax is public"
rescue NoMethodError
puts "tax is private"
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