Explicit Privates
The private
keyword in Ruby makes all instance methods declared after it private. There are a few different styles and ways of formatting it, but the most common style is this.
class Stuff
def something_public
# …
end
private
def something_private
# …
end
end
I’ve always found this to be a bit awful. If your file is large, the only way to know if a method you’re looking at is private or not is to keep scrolling upwards until you either see a private
or class
declaration. If you want to add a new method you have to do the same thing in order to make sure you’re putting the method in the right spot.
Rubyists do this so often that it becomes reflexive and habitual. We’ve internalized this as normal and we don’t really think about how weird it is. I think there’s a better way, though.
You might be aware that the private
declaration doesn’t affect class methods.
class Stuff
private
def self.something_private
# Not actually private
end
end
Never having tried to directly call a class method I’d declared as private, I didn’t discover this for years. To actually make a class method private you have to use a one-off private_class_method
declaration.
class Stuff
def self.something_private
# Now this is private
end
private_class_method :something_private
end
I wondered if that also works for private
, and it does!
class Stuff
def something_private
# This is private
end
private :something_private
end
And even better, the private declarations can be inlined.
class Stuff
def something_public
# …
end
private def something_private
# …
end
private_class_method def self.classy_private
# …
end
end
This works because the return value of a method declaration is the method name as a symbol, which gets passed as an argument to private
and private_class_method
.
Your initial reaction might be that this looks awful, but I encourage you to try it anyway. I think you’ll find that while it might not aesthetically look how you’re used to, it’s a relief knowing immediately whether the method you’re working on is public or private and not having to jump around to find out. I’ve been using this for the last several months and it’s great.