Rubyでプライベートメソッドを配置する場所は?


95

ほとんどのブログ、チュートリアル、または本には、クラス/モジュールの下部にプライベートメソッドがあります。これはベストプラクティスですか?

必要に応じてプライベートメソッドを使用する方が便利だと思います。例えば:

public
def my_method
  # do something
  minion_method
end

private
def minion_method
  # do something
end

public
def next_method
end

このようにして、連続的に上下にスクロールするのではなく、コードが読みやすくなるので、非常にイライラします。

このアプローチにひどい問題がありますか?下部にプライベートメソッドを設定するのは、ベストプラクティスやその他の方法だけではありませんか?


実際、あなたのやり方も悪くありません。私もいくつかのケースで同じに従います、それはより便利に感じますprivate def my_method...end
r3bo0t

回答:


131

私の観点からのベストプラクティスは、順番に進み、非公開の観点からメソッドを宣言しないことです。

最後に、次のコードを追加するだけで、メソッドをプライベートにできます。 private :xmethod

例:

class Example
 def xmethod
 end

 def ymethod
 end

 def zmethod 
 end

 private :xmethod, :zmethod

end

これはあなたの質問を正当化しますか?


19
クラスがどんどん長くなるので、これは読みやすさの観点からは素晴らしいアイデアではないと思います。
Alexander Suraphel、2016年

2
他のすべてのものが等しいと思われる場合、重要度の順序、および何を呼び出すかによってメソッドをソートする必要があると私は本当に思います。プライベートメソッドは実装の詳細であり、読者が最後に見るものであるため、ファイルの下位に属します。これは大きなファイルではうまく機能しないという上記のコメントに同意します。これは受け入れるべき答えではないはずです。このページにはもっと良いアドバイスがあります。
ルークコーウェル2017年

58

privateRuby 2.1以降、メソッド定義の前に追加するオプションもあります。

class Example

 def xmethod
 end

 private def ymethod
 end

 private def zmethod 
 end

end

定義を見ると、ファイル内のどこに定義されていても、メソッドがプライベートであるかどうかがすぐにわかります。(オートコンプリートを行わない場合は)少しタイピングが多く、すべてdefのがうまく整列するわけではありません。


5
これはRuby 2.1で利用可能であり、メソッドが独自の名前のキーを返すというバグ
konole

私は民間の缶にも別名プライベート始める...最後に、いくつかのプライベートメソッドを囲む、ブロックとして使用することと信じて
EDX

クラスメソッドを使用してこれを行う方法については、ここの @devpuppyの回答を参照してください。
マンロー

private前に1回だけ追加してymethodも機能します。複数回追加する必要はありません。
Iulian Onofrei 2018年

@IulianOnofrei zmethodなしprivateで以下の別のメソッドがある場合、このメソッドはプライベートではありません。したがって、これを繰り返す必要があります(少なくともRuby 2.3では)。
tsauerwein

52

他の人がすでに指摘しているように、規約はプライベートメソッドを1つのプライベートクラスの下に置くことです。ただし、多くのプログラマーがこれに二重インデント(2ではなく4スペース)を使用することも知っているはずです。その理由は、多くの場合、テキストエディターに「プライベート」と表示されず、それらがパブリックであることを想定していないためです。以下の図を参照してください。

class FooBar

  def some_public_method
  end

  def another_public_method
  end

private

    def some_private_method
    end

    def another_private method
    end

end

この方法を使用すると、上下にスクロールする必要がなくなり、他のプログラマーがコードをより快適に使用できるようになります。


4
12年にこのコメントを残したとき、これは大流行でした。私はこれをあまり頻繁に見なくなり、好意から外れました。
ノアクラーク

プライベートは、begin..end直後に内部でフォーマットすることもできprivateます。次に、インデントはエディターによって自動的に設定できます。これbeginは、(上記の例では)内部のコードが意味的に4つのスペースでインデントされているためです。
Petrus Repo

私は同じアプローチに従います...最初publicと次にprivate
Rahul Goyal

1
私はこれを見たことがなく、2007年からRubyを使用しています。通常はお勧めしません。
Marnen Laibow-Koser

15

パブリックメソッドはオブジェクトのインターフェイスの一種であり、最も目立つ場所、つまりファイルの先頭に配置するのが合理的だと思います。


5
はい、パブリックメソッドを見つけやすい場所に配置します。一般的にはファイルの上部に配置し、表示してはいけないものは下部に埋め込みます。新聞記事が書かれるように、最も重要なことを最初に置きます。
tadman

14

各メソッドの上publicまたはprivate上に置く必要はありません。私は通常、すべてのプライベートメソッドをクラスの一番下に配置します。また、publicメソッドはデフォルトでパブリックであるため、明示的に言う必要はありません。例えば:

class FooBar

  def some_public_method
  end

  def another_public_method
  end

private

  def some_private_method
  end

  def another_private method
  end

end

私の質問をもう一度読んでください。より具体的になるように編集しました
ZX12R

1
それは何よりも慣例です。あなたがやっていることは有効であり、それがあなたにとってより理にかなっているなら、あなたはそれに固執するべきです。私はこの規約が読みやすくなっていると思いますが、それはおそらく、それが私がそれを書くように教えられたので、慣れているからです。
Kyle Decot

メソッドを「パブリック」として宣言すると、実際には何を意味しますか?
ZX12R

6

私はJavaのバックグラウンドから来ており、メソッドタイプを表示するためにスクロールする必要がありません。醜さなくしてメソッドごとにメソッドの可視性を指定できないのはおかしいと思います。そのため、#private各suckメソッドの前にコメントを付けて宣言しましたprivate :...


1
そして最近のルビーprivate def method...はそれをより良くするために置くことができます
akostadinov

5

メソッドごとにpublicまたはprivateを指定する必要がありません。すべてのプライベートメソッドを下部に配置すると、ファイルごとに「プライベート」の単一のインスタンスを使用できます。それは好みの問題だと思います。


5

一つのスタイルは一緒ので、あなただけ使用することをグループの方法にあるprivateprotected、クラスごとに一度せいぜい。別のスタイルは、メソッド定義の直後に可視性を指定することです:

class Example
  def my_private_method
  end
  private :my_private_method

  def my_public_method
  end
end

Ruby 2.1.0以降でdefは、メソッド名をシンボルとして返すため、より効率的なスタイルが可能です。

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

private_class_methodクラスメソッドに使用することに注意してください。それ以外の場合はインスタンスメソッドを期待するためNameError: undefined method、取得されprivateます。元の例のようにマクロとして使用する場合でも、インスタンスメソッドの可視性にのみ影響します。)

このインライン表示スタイルは、メソッドを自由に整理できるので、一番気に入っています。これにより、間違った場所に新しいメソッドを追加して、それを誤って非公開にするリスクが減少します。

クラスメソッドの構文については、代わりに次のように処理できます。

class Example
  private def my_private_method
  end

  class << self
    private def my_private_class_method
    end
  end
end

これは私がprivate_class_method以前に呼び出しについて言及したのを見た唯一の場所であり、class << selfそれを使用する必要を避けるためのブロックの使用に関する最後の部分は良いヒントです。今までは、私が使用して宣言(つまり「nornal」クラスメソッドを知らなかったdef self.foo; endの代わりclass << self; def foo; endに影響されないでしょうprivate指定。
manroe

3

デニスは完璧な答えを出しました。つまり、ルビ> = 2.1を使用する場合は、defの前にprivate(またはprotected、public)を付けます。

しかし、次のようにブロックとしてプライベートを使用することも可能になったと思います。

private begin
   def foo
   end
   def bar
   end
end

def zip
end

0

私は通常、メソッドを次のように注文します。

  1. コンストラクタ
  2. その他のパブリックメソッド(アルファベット順)
  3. private、一度だけ書かれた
  4. アルファベット順のプライベートメソッド

エディターで「定義に移動」機能を使用して、スクロールがそれほど必要ないようにします。いずれにしても、クラスが大きくてスクロールが問題になる場合は、おそらくいくつかのクラスに分割する必要があります。


また、通常は変換メソッド(などto_s)をパブリックセクションの末尾近くに配置していることにも触れておきます。
Marnen Laibow-Koser
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.