Rubyのシングルトンクラスはそれ自体がクラスですか? すべてのオブジェクトが「クラス」に属するのはそのためですか。概念はあいまいですが、クラスメソッドを定義できる理由と関係があると思います ( class foo; def foo.bar ...
)。
Rubyのシングルトンクラスとは?
まず、簡単な定義:シングルトン メソッドは、単一のオブジェクトに対してのみ定義されるメソッドです。例:
irb(main):001:0> class Foo; def method1; puts 1; end; end
=> nil
irb(main):002:0> foo = Foo.new
=> #<Foo:0xb79fa724>
irb(main):003:0> def foo.method2; puts 2; end
=> nil
irb(main):004:0> foo.method1
1
=> nil
irb(main):005:0> foo.method2
2
=> nil
irb(main):006:0> other_foo = Foo.new
=> #<Foo:0xb79f0ef4>
irb(main):007:0> other_foo.method1
1
=> nil
irb(main):008:0> other_foo.method2
NoMethodError: undefined method `method2' for #<Foo:0xb79f0ef4>
from (irb):8
インスタンス メソッドは、クラスのメソッドです (つまり、クラスの定義で定義されます)。クラス メソッドはClass
、クラスのインスタンスに対するシングルトン メソッドです。クラスの定義では定義されていません。代わりに、オブジェクトのシングルトン クラスで定義されます。
irb(main):009:0> Foo.method_defined? :method1
=> true
irb(main):010:0> Foo.method_defined? :method2
=> false
構文でオブジェクトのシングルトン クラスを開きますclass << obj
。ここでは、このシングルトン クラスでシングルトン メソッドが定義されていることがわかります。
irb(main):012:0> singleton_class = ( class << foo; self; end )
=> #<Class:#<Foo:0xb79fa724>>
irb(main):013:0> singleton_class.method_defined? :method1
=> true
irb(main):014:0> singleton_class.method_defined? :method2
=> true
irb(main):015:0> other_singleton_class = ( class << other_foo; self; end )
=> #<Class:#<Foo:0xb79f0ef4>>
irb(main):016:0> other_singleton_class.method_defined? :method1
=> true
irb(main):017:0> other_singleton_class.method_defined? :method2
=> false
したがって、シングルトン メソッドをオブジェクトに追加する別の方法は、オブジェクトのシングルトン クラスを開いた状態で定義することです。
irb(main):018:0> class << foo; def method3; puts 3; end; end
=> nil
irb(main):019:0> foo.method3
3
=> nil
irb(main):022:0> Foo.method_defined? :method3
=> false
要約すれば:
Class
Ruby では、特定のオブジェクトに固有のメソッドを定義する方法が提供されており、そのようなメソッドはシングルトン メソッドとして知られています。オブジェクトでシングルトン メソッドを宣言すると、Ruby はシングルトン メソッドだけを保持するクラスを自動的に作成します。新しく作成されたクラスはシングルトン クラスと呼ばれます。
foo = Array.new
def foo.size
"Hello World!"
end
foo.size # => "Hello World!"
foo.class # => Array
#Create another instance of Array Class and call size method on it
bar = Array.new
bar.size # => 0
シングルトン クラスは、オブジェクト固有の匿名クラスであり、自動的に作成されて継承階層に挿入されます。
singleton_methods
オブジェクトで呼び出して、オブジェクトのすべてのシングルトン メソッドの名前のリストを取得できます。
foo.singleton_methods # => [:size]
bar.singleton_methods # => []
この記事は、Ruby のシングルトン クラスを理解するのに非常に役立ちました。また、適切なコード例も含まれています。
それを考える最も実用的/アクション指向の方法(IMHO)は、継承チェーン、またはメソッドのルックアップ/解決順序としてです。この写真は役立つかもしれません
http://www.klankboomklang.com/2007/11/25/modules-part-i-enter-the-include-class/
これはr1.9であり、組み込みクラスとユーザー定義クラスを対比しています。私はまだこれを消化しています。
http://d.hatena.ne.jp/sumim/20080111/p1
また、この用語の紛らわしい使用法は、別の概念である「シングルトンオブジェクト」だと思います。シングルトンオブジェクトは、コンストラクター/インスタンス化メソッドがオーバーライドされているクラスから取得されるため、そのクラスの1つだけを割り当てることができます。
シングルトン クラスとは、簡単に言うと、Ruby が個々のオブジェクトで定義されたホスト メソッドを作成する特別なクラスです。ruby では、個々のオブジェクトに対して、そのオブジェクトだけに固有のメソッドを定義することができます。たとえば、以下のことを考慮してください
class User; end
user = User.new
def user.age
"i'm a unique method"
end
user1 = User.new
user.age #"i'm a unique method"
user1.age # NoMethodError (undefined method `age' for #<User:0x0000559c66ab7338>)
上記のように、user1 オブジェクトは「age」メソッドに応答しません。これは、ユーザー オブジェクトで一意に定義されたメソッドであるシングルトン メソッドであるためです。これを実現するために、ruby は、この独自のメソッドをホストするために、singleton クラスまたは eigenclass と呼ばれる特別なクラスを作成します。これは、次の手順で確認できます。
user.singleton_class # #<Class:#<User:0x0000559c66b47c58>>
メソッド オブジェクトを使用して、メソッド「age」が定義されている場所を調べることで、「age」メソッドがここにあるかどうかを ruby に問い合わせることもできます。これを行うと、シングルトン クラスにそのメソッドがあることがわかります。
user_singleton_class = user.method(:age).owner # #<Class:#<User:0x0000559c66b47c58>>
user.method(:age).owner == user.singleton_class # true
user_singleton_class.instance_methods(false) # [:age]
また、シングルトン クラスに関する限り、シングルトン メソッドは実際にはインスタンス メソッドであることに注意してください。
user.singleton_methods == user_singleton_class.instance_methods(false) # true