A baker can accept a request to bake a cake without accepting separate requests to crack an egg or stir batter. Ruby’s private instance methods make that distinction: an object can use these methods to do its work, while callers cannot invoke them with an explicit receiver other than self. Instance methods are public unless their access level is changed. section 5.3 section 5.3.1 section 5.4.1
Listing 5.8 Baker and other baking-domain classes
class Cake
def initialize(batter)
@batter = batter
@baked = true
end
end
class Egg
end
class Flour
end
class Baker
def bake_cake
@batter = [] #1
pour_flour
add_egg
stir_batter
return Cake.new(@batter) #2
end
private 1
def pour_flour
@batter.push(Flour.new) #3
end
def add_egg
@batter.push(Egg.new)
end
def stir_batter
end
end
Follow bake_cake: it calls pour_flour, add_egg, and stir_batter without receivers. The private declaration makes the methods defined below it private; bake_cake remains public. section 5.3.1
Calling b.add_egg fails because b is an explicit receiver. Inside a Baker instance method, bare add_egg works: Ruby sends a call without an explicit receiver to the current object, self. An explicit self.add_egg also works. The distinction is about the receiver written at the call site, not whether the method has a receiving object. section 5.3.1 section 5.4.1
Two ways to declare private methods are:
- Place private before method definitions. Subsequent instance methods are private until another access declaration, such as public or protected, changes the setting. section 5.3.1
- Name methods explicitly, as in private :pour_flour, :add_egg, :stir_batter. section 5.3.1
A private setter
A setter needs special care. In an age= method that updates a private dog_years= method, write self.dog_years = years * 7. Without self, the assignment is to a local variable rather than a call to the setter. This is the usual exception to the preference for bare private-method calls. section 5.3.1 section 5.4.1
A method defined at the top level can likewise be called as a bareword from elsewhere: it is available as a private instance method through the Object and Kernel method-lookup path, not as a public method on an arbitrary object. To inspect an object’s private method names, call private_methods; a method you declare private appears in that list. section 5.4.1 section 5.5 section 15.2.2
Privacy also matters when invoking methods by name. send can call a private method, whereas public_send cannot. If a method name comes from user input, check or restrict the allowed names rather than passing the input unchecked to send. section 2.3.3











