class << self
はRubyで何をするの?
まず、class << foo
構文はfoo
のシングルトンクラス(固有クラス)を開きます。これにより、その特定のオブジェクトで呼び出されるメソッドの動作を特殊化できます。
a = 'foo'
class << a
def inspect
'"bar"'
end
end
a.inspect # => "bar"
a = 'foo' # new object, new singleton class
a.inspect # => "foo"
ここで、質問に答えるために:class << self
がself
のシングルトンクラスを開き、メソッドが現在のself
オブジェクト(クラスまたはモジュール本体内でクラスまたはモジュールである)に対して再定義できるようにしますそれ自体)。通常、これはクラス/モジュール(「静的」)メソッドを定義するために使用されます。
class String
class << self
def value_of obj
obj.to_s
end
end
end
String.value_of 42 # => "42"
これは略記として書くこともできます:
class String
def self.value_of obj
obj.to_s
end
end
またはさらに短く:
def String.value_of obj
obj.to_s
end
関数定義内では、self
は関数が呼び出されるオブジェクトを参照します。この場合、class << self
はそのオブジェクトのシングルトンクラスを開きます。その使用法の1つは、貧乏人の状態マシンを実装することです。
class StateMachineExample
def process obj
process_hook obj
end
private
def process_state_1 obj
# ...
class << self
alias process_hook process_state_2
end
end
def process_state_2 obj
# ...
class << self
alias process_hook process_state_1
end
end
# Set up initial state
alias process_hook process_state_1
end
したがって、上記の例では、StateMachineExample
の各インスタンスはprocess_hook
にエイリアスされたprocess_state_1
を持っていますが、後者ではprocess_hook
を再定義できることに注意してください(self
のみ、他のStateMachineExample
インスタンスに影響しない)からprocess_state_2
へ。そのため、呼び出し元がprocess
メソッド(再定義可能なprocess_hook
を呼び出す)を呼び出すたびに、その状態に応じて動作が変わります。
私はこの ブログ でclass << self
、Eigenclass
、および異なるタイプのmethods
に関する非常に単純な説明を見つけました。
Rubyでは、クラスに適用できるメソッドは3種類あります。
インスタンスメソッドとクラスメソッドは、他のプログラミング言語での同名のメソッドとほとんど同じです。
class Foo
def an_instance_method
puts "I am an instance method"
end
def self.a_class_method
puts "I am a class method"
end
end
foo = Foo.new
def foo.a_singleton_method
puts "I am a singletone method"
end
Eigenclass
(シングルトンメソッドを含む)にアクセスするもう1つの方法は、次の構文(class <<
)を使用することです。
foo = Foo.new
class << foo
def a_singleton_method
puts "I am a singleton method"
end
end
これで、self
のシングルトンメソッドを定義できます。これは、このコンテキストではクラスFoo
自体です。
class Foo
class << self
def a_singleton_and_class_method
puts "I am a singleton method for self and a class method for Foo"
end
end
end
通常、インスタンスメソッドはグローバルメソッドです。それは、それらが定義されたクラスのすべてのインスタンスでそれらが利用可能であることを意味します。対照的に、シングルトンメソッドは単一のオブジェクトに実装されています。
Rubyはメソッドをクラスに格納し、すべてのメソッドはクラスに関連付けられなければなりません。シングルトンメソッドが定義されているオブジェクトはクラスではありません(これはクラスのインスタンスです)。クラスだけがメソッドを格納できる場合、オブジェクトはシングルトンメソッドをどのように格納できますか?シングルトンメソッドが作成されると、Rubyはそのメソッドを格納するための匿名クラスを自動的に作成します。これらの無名クラスはメタクラスと呼ばれ、シングルトンクラスまたはエイジクラスとしても知られています。シングルトンメソッドはメタクラスに関連付けられており、メタクラスはシングルトンメソッドが定義されているオブジェクトに関連付けられています。
単一のオブジェクト内に複数のシングルトンメソッドが定義されている場合、それらはすべて同じメタクラスに格納されます。
class Zen
end
z1 = Zen.new
z2 = Zen.new
class << z1
def say_hello
puts "Hello!"
end
end
z1.say_hello # Output: Hello!
z2.say_hello # Output: NoMethodError: undefined method `say_hello'…
上記の例では、クラス<< z1は現在の自己をz1オブジェクトのメタクラスを指すように変更します。次に、メタクラス内でsay_helloメソッドを定義します。
クラスはオブジェクト(Classという組み込みクラスのインスタンス)でもあります。クラスメソッドは、クラスオブジェクトに関連付けられたシングルトンメソッドに他なりません。
class Zabuton
class << self
def stuff
puts "Stuffing zabuton…"
end
end
end
すべてのオブジェクトはメタクラスを持つことができます。つまり、クラスはメタクラスも持つことができます。上記の例では、class << selfはselfを変更してZabutonクラスのメタクラスを指すようにします。メソッドが明示的なレシーバ(メソッドが定義されるクラス/オブジェクト)なしで定義されている場合、それは現在のスコープ内、つまりselfの現在の値内で暗黙的に定義されます。したがって、stuffメソッドはZabutonクラスのメタクラス内で定義されています。上記の例は、クラスメソッドを定義するための別の方法です。私見、それはコードを理解しやすくするので、クラスメソッドを定義するためにdef self.my_new_clas_method構文を使用する方が良いです。上記の例は含まれているので、クラス<< selfの構文に出くわしたときに何が起こっているのか理解できます。
Ruby Classesに関する追加情報は この投稿で見つけることができます 。
class Hi
self #=> Hi
class << self #same as 'class << Hi'
self #=> #<Class:Hi>
self == Hi.singleton_class #=> true
end
end
[そのブロックの文脈でself == thing.singleton_class
にする]。
hi = String.new
def hi.a
end
hi.class.instance_methods.include? :a #=> false
hi.singleton_class.instance_methods.include? :a #=> true
hi
オブジェクトは、その#methods
からその#singleton_class.instance_methods
を継承し、次にその#class.instance_methods
から継承します。
ここではhi
シングルトンクラスインスタンスメソッド:a
を与えました。代わりにクラス<< hiを使用して行った可能性があります。hi
の#singleton_class
はすべてのインスタンスメソッドを持っていますhi
の#class
、そしておそらくそれ以上のもの(ここでは:a
)。
[thingのインスタンスメソッド#class
と#singleton_class
のインスタンスメソッドは、thingに直接適用できます。 Rubyがthing.aを見たとき、まずそれを探します:thing.singleton_class.instance_methodsの中の、そしてそれからthing.class.instance_methodsの中のメソッド定義]
ところで - 彼らはオブジェクトのシングルトンクラス==メタクラス==eigenclass.
Аシングルトンメソッドは、単一のオブジェクトに対してのみ定義されるメソッドです。
例:
class SomeClass
class << self
def test
end
end
end
test_obj = SomeClass.new
def test_obj.test_2
end
class << test_obj
def test_3
end
end
puts "Singleton's methods of SomeClass"
puts SomeClass.singleton_methods
puts '------------------------------------------'
puts "Singleton's methods of test_obj"
puts test_obj.singleton_methods
シングルトンのSomeClassメソッド
テスト
シングルトンのtest_objメソッド
test_2
test_3
実際にあなたのRubyプロジェクトのためにC拡張を書くなら、Moduleメソッドを定義する唯一の方法があります。
rb_define_singleton_method
私はこの自営業が他のあらゆる種類の質問を開くだけであることを知っているので、あなたはそれぞれの部分を検索することによってよりよくすることができました。
最初にオブジェクト。
foo = Object.new
Foo用のメソッドを作ることができますか?
もちろん
def foo.hello
'hello'
end
私はそれで何をしますか?
foo.hello
==>"hello"
もう一つのオブジェクト。
foo.methods
あなたはすべてのObjectメソッドとあなたの新しいものを手に入れる。
def foo.self
self
end
foo.self
ただのfooオブジェクト。
ClassやModuleのような他のオブジェクトからfooを作ったらどうなるか見てみてください。すべての答えの例はうまくいきますが、コードの作成方法で何が起こっているのかを実際に理解するには、さまざまなアイデアや概念を扱う必要があります。だから今あなたは見に行くための用語がたくさんあります。
Singleton、Class、Module、self、Object、そしてEigenclassが登場しましたが、RubyはそのようにObject Modelsを名付けていません。それはメタクラスのようなものです。 Richardか__whyがあなたにここでその考えを示しています。 http://viewsourcecode.org/why/hacking/seeingMetaclassesClearly.html そしてもしあなたがいなくなったら、Ruby Object Modelを検索してみてください。私がYouTubeで知っている2つのビデオは、Dave ThomasとPeter Cooperです。彼らはその概念も説明しようとしています。それを取得するのに長い時間がかかりましたので心配しないでください。私はまだそれに取り組んでいます。他になぜ私はここにいるのでしょうか?ご質問ありがとうございます。標準ライブラリも見てください。それはちょうどFYIとしてシングルトンモジュールを持っています。
これはかなり良いです。 https://www.youtube.com/watch?v=i4uiyWA8eFk