69

このRuby スタイル ガイドは、self.method_nameの代わりに を使用する方がよいことを示していclass method_nameます。しかし、なぜ?

class TestClass
  # bad
  class << self
    def first_method
      # body omitted
    end

    def second_method_etc
      # body omitted
    end
  end

  # good
  def self.first_method
    # body omitted
  end

  def self.second_method_etc
    # body omitted
  end
end

パフォーマンスの問題はありますか?

4

6 に答える 6

101

class << selfすべてのクラスメソッドを同じブロックに保持するのが得意です。メソッドがdef self.methodフォームに追加されている場合、ファイルの後半に余分なクラスメソッドが隠れていないという保証はありません(慣例と希望的観測以外)。

def self.methodメソッドがクラスメソッドであることを明示的に示すのは得意class << selfですが、コンテナを自分で見つけに行く必要があります。

これらのどれがあなたにとってより重要であるかは主観的な決定であり、コードに取り組んでいる他の人の数や彼らの好みなどにも依存します。

于 2012-06-09T20:04:15.320 に答える
31

一般に、class << selfメタプログラミングでクラスを長時間自己として設定するために使用されます。10 個のメソッドを記述しようとしている場合は、次のように使用します。

METHOD_APPENDICES = [1...10]
class << self
  METHOD_APPENDICES.each do |n|
    define_method("method#{n}") { n }
  end
end

これにより、数値を返すだけの 10 個のメソッド (method1、method2、method3 など) が作成されます。メタプログラミングでは重要class << selfであるため、この場合は明確にするために使用します。selfそこにポイ捨てself.すると、実際には読みにくくなります。

クラスメソッドを普通に定義しているだけならself.class_method_name、より多くの人が理解できる可能性が高いので、それに固執してください。聴衆がそれを理解することを期待しない限り、メタ構文を持ち込む必要はありません。

于 2012-06-09T20:35:42.407 に答える
28

上で述べたように、どちらのスタイルも同じように見えますが、 を使用すると、class << selfクラス メソッドをprivateまたはとしてマークできますprotected。例えば:

class UsingDefSelf
  def self.a; 'public class method'; end
  private
  def self.b; 'public class method!'; end
end

class UsingSingletonClass
  class << self
    def a; 'public class method'; end
    private
    def b; 'private class method'; end
  end
end

privateインスタンスメソッドのみに影響します。シングルトン クラスを使用して、そのクラスのインスタンス メソッドを定義しています。これは、包含クラスのクラス メソッドに変わります!

クラスメソッドを次のようにマークすることもできprivateますdef self:

class UsingDefSelf
  def self.a; 'private class method'; end
  def self.b; 'private class method!'; end
  private_class_method :a, :b
  # In Ruby 2.1 there is an alternative syntax
  private_class_method def self.c; 'private class method!'; end
end

しかし、それらを としてマークすることはできませprotectedprotected_class_method。(ただし、class はその singletonclass の唯一のインスタンスであるため、private クラスのメソッドと保護されたクラスのメソッドは、呼び出し構文が異なることを除いてほとんど同じです。)

また、すべてのプライベート クラス メソッド定義にすべてのメソッド名またはプレフィックスをリストする必要があるため、クラス メソッドclass << selfをマークするために使用するよりも簡単ではありません。privateprivate_class_methodprivate_class_method

于 2015-01-09T18:09:21.907 に答える
6

どちらでも構いません。どちらもあなたが何をするかについて非常に明確です。しかし、私はこれについていくつかの推奨事項を考えています。

定義するクラス メソッドが 1 つしかない場合は、 Use def self.xxx. メソッドを 1 つだけ定義するために、インデント レベルを上げると、おそらく煩雑になるからです。

定義するクラス メソッドが複数ある場合は、を使用しclass << selfます。と書いてあるので、def self.xxx確かに繰り返しです。これらのメソッドのセクションを作成します。def self.yyydef self.zzz

クラス内のすべてのメソッドがクラス メソッドの場合、の代わりにmodulewithを使用できます。これにより、使用するモジュール関数を定義できます。module_functionclassdef xxx

于 2012-06-09T23:14:39.923 に答える
5

self.*上にスクロールしてこの文字列を検索しなくても、クラスまたはインスタンスメソッドであると確実に言うことができるので、彼らはより良いと考えていると思いclass << selfます。

于 2012-06-09T19:58:00.083 に答える
-3

これまでのところ、質問と回答では、次の 2 つのオプションについてのみ説明しています。

class MyClass
  def self.method_name
    ..
  end
end

class MyClass
  class << self
    def method_name
      ..
    end
  end
end

クラス メソッドについて考慮すべき 3 番目のオプションがあります。

class MyClass
  def MyClass.method_name
    ..
  end
end

これは一般的ではなく、より冗長ですが、最も明示的なオプションです。

selfまた、Python と Ruby の動作を混同しても混乱しません。

于 2015-01-16T09:42:25.317 に答える