Where to place private methods in Ruby?

RubyConventions

Ruby Problem Overview


Most of the blogs or tutorials or books have private methods at the bottom of any class/module. Is this the best practice?

I find having private methods as and when necessary more convenient. For example:

public
def my_method
  # do something
  minion_method
end

private
def minion_method
  # do something
end

public
def next_method
end

This way I find the code more readable instead of scrolling up and down continuously which is very irritating.

Is there something terribly wrong in this approach? Is having private methods at the bottom not just a best practice and something else?

Ruby Solutions


Solution 1 - Ruby

The best practice in my point of view is to go sequentially and declare your methods without keeping private in point of view.

At the end, you can make make any method private by just adding: private :xmethod

Example:

class Example
 def xmethod
 end

 def ymethod
 end

 def zmethod 
 end

 private :xmethod, :zmethod

end

Does this justify your question?

Solution 2 - Ruby

There's also the option to prepend private to the method definition since Ruby 2.1.

class Example
 def xmethod
 end

 private def ymethod
 end

 private_class_method def self.zmethod 
 end
end

You can instantly see if a method is private, no matter where in the (large) file it is. And it's consistent with many other languages. But it's a bit more typing and doesn't nicely align.

Solution 3 - Ruby

As others have already pointed out the convention is to put private methods at the bottom, under one private class. However, you should probably also know that many programers use a double indented (4 spaces instead of 2) method for this. The reason is that often times you won't see "private" in your text editor and assume they could be public. See below for an illustration:

class FooBar

  def some_public_method
  end

  def another_public_method
  end

private

    def some_private_method
    end

    def another_private method
    end

end

This method should prevent you from having to scroll up and down and will make other programmers more comfortable in your code.

Solution 4 - Ruby

I think that public methods is a some kind of interface of the object, and it's logical to place them on the most prominent place i.e. in the top of file.

Solution 5 - Ruby

You don't need to put public or private above each method. I usually put all of my private methods at the bottom of my class. Also, don't have to explicitly say public as methods are public by default. For example:

class FooBar
  
  def some_public_method
  end

  def another_public_method
  end

private

  def some_private_method
  end

  def another_private method
  end
  
end

Solution 6 - Ruby

One style is to group methods together so that you only use private and protected once per class at most. Another style is to specify visibility right after the method definition:

class Example
  def my_private_method
  end
  private :my_private_method

  def my_public_method
  end
end

As of Ruby 2.1.0 def returns the method name as a symbol, so a more streamlined style is possible:

class Example
  private def my_private_method
  end

  def my_public_method
  end

  protected def my_protected_method
  end

  private_class_method def self.my_private_class_method
  end
end

(Note that we use private_class_method for class methods -- otherwise we'd get NameError: undefined method since private expects an instance method. Even when using it as a macro like in the original example it only affects the visibility of instance methods.)

I like this inline visibility style best, as it allows you to organize methods as you wish. It decreases the risk of adding a new method in the wrong place and inadvertently making it private.

As for the class method syntax, you can handle it this way instead:

class Example
  private def my_private_method
  end
  
  class << self
    private def my_private_class_method
    end
  end
end

Solution 7 - Ruby

I'm coming from java background and I hate to have to scroll to see method type. I think it's insane that one cannot specify method visibility per method without ugliness. So I ended up putting a comment #private before each suck method and then declaring private :....

Update: In recent ruby one can write private def method_name so the above is much less relevant.

Update 2: actually see @devpuppy's answer, it has more explanation.

Solution 8 - Ruby

I don't like having to specify public or private for each method. Putting all private methods at the bottom lets me have a single instance of "private" per file. I guess it's a matter of taste.

Solution 9 - Ruby

Dennis had the perfect answer, that is, when using ruby >=2.1, just prefix the def with private (or protected,public)

But I believe that it's now also possible to use private as a block as in:

private begin
   def foo
   end
   def bar
   end
end

def zip
end

Solution 10 - Ruby

I generally order my methods as follows:

  1. Constructor
  2. Other public methods, in alphabetical order
  3. private, written only once
  4. Private methods, in alphabetical order

I use “go to definition” features in my editor so that this doesn’t involve much scrolling, and in any case, if the class is big enough that scrolling becomes problematic, it probably should be broken up into several classes.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionZX12RView Question on Stackoverflow
Solution 1 - RubykiddorailsView Answer on Stackoverflow
Solution 2 - RubyDennisView Answer on Stackoverflow
Solution 3 - RubyNoah ClarkView Answer on Stackoverflow
Solution 4 - RubyFlexoidView Answer on Stackoverflow
Solution 5 - RubyKyle DecotView Answer on Stackoverflow
Solution 6 - RubydevpuppyView Answer on Stackoverflow
Solution 7 - RubyakostadinovView Answer on Stackoverflow
Solution 8 - RubyDavidView Answer on Stackoverflow
Solution 9 - RubyedxView Answer on Stackoverflow
Solution 10 - RubyMarnen Laibow-KoserView Answer on Stackoverflow