2


1

Rubyでクラスメソッドを定義するには、次の2つの方法があります。

クラスFooクラス<< self def bar#... 終末

def self.baz#... 終末

両者に違いはありますか? 一方が他方よりも好ましいですか?

4 Answer


3


一言で言えば:いいえといいえ。

それは個人的な好み次第です。 最初のバージョンでは、多くのクラスメソッドを定義していると入力の手間が省けます。 2番目の構文は、最初の構文の曖昧な構文が嫌いな場合に適しています。


3


用語を明確にするために、Rubyには "クラスメソッド"のようなものはありません。 あなたがしているのは、クラス+ Foo である_object_で_singleton method_を定義することです(クラスは他のクラスと同様にオブジェクトでもあります)。 同様に、シングルトンメソッドも実際には存在せず、オブジェクトの_eigenclass_(一般に「 Foo」+」と呼ばれる)上の通常のインスタンスメソッドであり、この場合はクラスのメタクラス ` + Foo + `。

まだ混乱している? :-)

基本的に、これを行うことと違いはありません。

foo = Object.new
class << foo
  def bar
    # ...
  end
end

def foo.baz
  # ...
end

この:

class Foo
  class << self
    def bar
      # ...
    end
  end

  def self.baz
    # ...
  end
end

クラス定義内では、 + self +`がクラスオブジェクト(この場合は `+ Foo +)にバインドされているため、以下と同等です。

class Foo
  class << Foo
    def bar
      # ...
    end
  end

  def Foo.baz
    # ...
  end
end

これは次のものと同等です。

Foo = Class.new
class << Foo
  def bar
    # ...
  end
end

def Foo.baz
  # ...
end

あなたが見ることができるようにこれは私の最初の例とほとんどまったく同じです。 これは、クラスメソッド上のシングルトンメソッドと他の種類のオブジェクト上のシングルトンメソッドとの間には実際に違いがないことを示しているので、Rubyの「クラスメソッド」について話すことは意味がありません。

また、これら2つの表記法がシングルトンメソッドと固有クラスの概念とどのように関連しているかもわかります。

def foo.baz
  # ...
end

「シングルトンメソッド `+ baz `をオブジェクト ` foo +`に追加します」

class << foo
  def bar
    # ...
  end
end

「オブジェクト `+ foo `の固有クラスを開き、インスタンスメソッド ` bar +`を固有クラスに追加します。」 しかし、以前に確立したように、オブジェクトのシングルトンメソッドとオブジェクトの固有クラスのインスタンスメソッドは、まったく同じものです。 そのため、これら2つの表記法の動作が異なっても意味がありません。


0


molfが言ったように、効果的な違いはありません。 しかし、IMO、2番目は非常にスキム可能です-`+ class <を見逃して、まだインスタンスメソッドを見ていると思うのは簡単すぎます。 クラス自体のattr_accessor + `プロパティを作成するなど、より動的な動作が必要な場合にのみ、class <ルートを使用する傾向があります。


0


オプション1。 `+ class << self `と対応する ` end `の間に多くのコード行がある場合、問題が発生します。 メソッドが ` class << self +`ブロック内で定義されていることに気付かない場合、単なるインスタンスメソッドと考えるかもしれません。

オプション2 訓練されていないRubyの目には、よりタイピングされ、表現力があり、理解しやすいものです。

他の人がすでに指摘したように、それらは最終結果に違いはありません。