14

クラスのメソッドとそのクラスの固有クラス (またはメタクラス) のメソッドは、1 つのことを定義する 2 つの方法にすぎませんか?

そうでなければ、違いは何ですか?

class X
  # class method
  def self.a
    "a"
  end

  # eigenclass method
  class << self
    def b
      "b"
    end
  end
end

何らかの方法で異なる行動をしますX.aか?X.b

固有クラスを開くことで、クラス メソッドを上書きまたはエイリアスできることを認識しています。

irb(main):031:0> class X; def self.a; "a"; end; end
=> nil
irb(main):032:0> class X; class << self; alias_method :b, :a; end; end
=> #<Class:X>
irb(main):033:0> X.a
=> "a"
irb(main):034:0> X.b
=> "a"
irb(main):035:0> class X; class << self; def a; "c"; end; end; end
=> nil
irb(main):036:0> X.a
=> "c"
4

4 に答える 4

11

2 つの方法は同等です。'eigenclass' バージョンは、attr_* メソッドを使用する場合に役立ちます。次に例を示します。

class Foo
  @instances = []
  class << self;
    attr_reader :instances
  end
  def initialize
    self.class.instances << self
  end
end

2.times{ Foo.new }
p Foo.instances
#=> [#<Foo:0x2a3f020>, #<Foo:0x2a1a5c0>]

define_singleton_methodクラスでメソッドを作成するために使用することもできます。

Foo.define_singleton_method :bim do "bam!" end
于 2010-11-18T16:22:56.360 に答える
6

Ruby には、クラス メソッドのようなものは実際にはありません。Ruby ではすべてが (クラスを含めて) オブジェクトであるため、 と言うときはdef self.class_method、実際にはクラスのインスタンスにシングルトン メソッドを定義しているだけですClass。だからあなたの質問に答えるために、

class X
  def self.a
    puts "Hi"
  end

  class << self
    def b
      puts "there"
    end
  end
end

X.a # => Hi
X.b # => there

は同じことを 2 つの言い方で表しています。これらのメソッドは両方とも、あなたの例ではX. このトピックは、楽しいトピックであるメタプログラミングの一部であり、Ruby をしばらく使用している場合はチェックアウトする必要があります。Pragmatic Programmers には、メタプログラミングに関する優れたがあります。このトピックに興味がある場合は、必ず目を通すべきです。

于 2010-11-19T04:08:27.790 に答える
3

この古い質問を掘り起こすためにここにいるさらに別のネクロマンサー... 1 つ気付いていないかもしれないことの 1 つは、クラス メソッドをprivate( の代わりに private キーワードを使用して:private_class_method) としてマークすることは、固有クラス メソッドをそのようにマークすることとは異なるということです。:

class Foo
  class << self
    def baz
      puts "Eigenclass public method."
    end

    private
    def qux
      puts "Private method on eigenclass."
    end
  end
  private
  def self.bar
    puts "Private class method."
  end
end

Foo.bar
#=> Private class method.
Foo.baz
#=> Eigenclass public method.
Foo.qux
#=> NoMethodError: private method `qux' called for Foo:Class
#   from (irb)

次の例は、前の例が意図したとおりに機能します。

class Foo
  class << self
    def baz
      puts "Eigen class public method."
    end

    private
    def qux
      puts "Private method on eigenclass."
    end
  end
  def bar
    puts "Private class method."
  end
  private_class_method :bar
end
Foo.bar
#=> NoMethodError: private method `bar' called for Foo:Class
#     from (irb)
Foo.baz
#=> Eigen class public method.
Foo.qux
#=> NoMethodError: private method `qux' called for Foo:Class
#     from (irb)
于 2016-04-12T14:49:47.690 に答える