Every discussion of private vs. public Ruby methods in a class shows how to declare all following methods private (or public or protected):
class airplane
def preflight
end
def engine_start
return unless preflight_complete?
end
private
def preflight_complete?
end
end
That works great most of the time, where you put all your public methods at the top, and all your private methods down below.
I've got a good-sized class with three public methods, and a few dozen private ones. The private ones are all sequenced in a logical manner for developer comfort.
Now, I find there are 2 or 3 formerly-private methods I need to make public. I don't want to pull them to the top, away from their contextual neighbors. I also find it cludgey to flop back and forth between public and private each time. This is particularly annoying if the screen size pushes the public flag out of view and it's not obvious that a second or third new method are unintentionally public just because I inserted them after the loner public method.
So, is there a graceful way to avoid flopping public/private back and forth to make just one method public?
Just put public (or private, protected) at the start of the method definition:
class airplane
def preflight
end
def engine_start
return unless preflight_complete?
end
private
def preflight_complete?
end
public def tanks_full?
end
def pilot_authorized?
end
end
In this case, pilot_authorized? is still private, but anyone chan check tanks_full?
As an alternative, you can publish this method via a public wrapper.
class airplane
def preflight
end
def engine_start
return unless preflight_complete?
end
def tanks_full?
_tanks_full?
end
private
def preflight_complete?
end
def _tanks_full?
end
def pilot_authorized?
end
end
This way your code is still clearly divided into two sections, without any surprise defectors, and the method is still near its contextual neighbors.
This seems the most readable to me:
class Example
def public_method1
end
private def used_by_public_method1
end
private def also_used_by_public_method1
end
def public_method2
end
private def used_by_public_method2
end
def public_method3
end
end