Rubyでは何をしclass << self
ますか?
Rubyでは何をしclass << self
ますか?
回答:
まず、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
メソッド(redefinableを呼び出すprocess_hook
)を呼び出すたびに、その状態に応じて動作が変化します。
class << self
クラス/モジュールメソッドを作成するためののより一般的な使用方法です。私はおそらくclass << self
もっと慣用的な使用法であるため、その使用法を拡張します。
a
のsingleton_class
ため、a
(変更後のクラスのはinspect
)独特の変種であるString
クラス。シングルトンString
クラスを変更すると、他のすべてのString
インスタンスに影響します。さらに奇妙なのは、後で再び開いString
て再定義したinspect
場合a
でも、新しい変更が反映されることです。
class << self
以上の値よりも平均何をself
ブロックの範囲内でシングルトンクラスに等しく設定されていますか?
私は約スーパー簡単な説明を見つけclass << self
、Eigenclass
および方法の異なるタイプを。
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
(シングルトンメソッドを含む)、次の構文(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
foo.singleton_class.instance_methods(false)
確認に使用できます。
通常、インスタンスメソッドはグローバルメソッドです。つまり、それらが定義されたクラスのすべてのインスタンスで使用できます。対照的に、シングルトンメソッドは単一のオブジェクトに実装されます。
Rubyはメソッドをクラスに格納し、すべてのメソッドはクラスに関連付けられている必要があります。シングルトンメソッドが定義されているオブジェクトはクラスではありません(クラスのインスタンスです)。クラスだけがメソッドを格納できる場合、オブジェクトはどのようにシングルトンメソッドを格納できますか?シングルトンメソッドが作成されると、Rubyはそのメソッドを格納する匿名クラスを自動的に作成します。これらの匿名クラスはメタクラスと呼ばれ、シングルトンクラスまたは固有クラスとも呼ばれます。シングルトンメソッドはメタクラスに関連付けられ、メタクラスはシングルトンメソッドが定義されたオブジェクトに関連付けられます。
1つのオブジェクト内で複数のシングルトンメソッドが定義されている場合、それらはすべて同じメタクラスに格納されます。
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
すべてのオブジェクトはメタクラスを持つことができます。つまり、クラスはメタクラスを持つこともできます。上記の例では、クラス<< selfはZabutonクラスのメタクラスを指すようにselfを変更します。明示的なレシーバー(メソッドが定義されるクラス/オブジェクト)なしでメソッドが定義されると、現在のスコープ、つまりselfの現在の値内で暗黙的に定義されます。したがって、スタッフメソッドはZabutonクラスのメタクラス内で定義されます。上記の例は、クラスメソッドを定義するもう1つの方法です。私見、コードを理解しやすくするため、def self.my_new_clas_method構文を使用してクラスメソッドを定義することをお勧めします。上記の例は、クラス<<自己構文に遭遇したときに何が起きているかを理解するために含まれています。
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
s 'を#class
(持っている、そしておそらくいくつかのより多くの:a
ここでは)。
【もののインスタンスメソッド #class
と #singleton_class
の事に直接適用することができます。rubyがthing.aを見つけると、最初に:aメソッド定義をthing.singleton_class.instance_methodsで探し、次にthing.class.instance_methodsで探します]
ちなみに、オブジェクトのシングルトンクラス == metaclass == 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メソッドを定義する方法は1つしかありません。
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を作成するとどうなるかを確認してください。すべての回答の例を試すのは良いことですが、コードの記述方法で何が起こっているのかを本当に理解するには、さまざまなアイデアや概念を使用する必要があります。これで、検討すべき用語がたくさんあります。
シングルトン、クラス、モジュール、自己、オブジェクト、および固有クラスが登場しましたが、Rubyはオブジェクトモデルにそのような名前を付けていません。メタクラスに似ています。リチャードまたは__whyがここでアイデアを示します。 http://viewsourcecode.org/why/hacking/seeingMetaclassesClearly.html そして、もしあなたがたら、検索でRubyオブジェクトモデルを調べてみてください。私がYouTubeで知っている2つの動画は、Dave ThomasとPeter Cooperです。彼らはその概念も説明しようとしています。Daveを取得するのに長い時間がかかったので、心配しないでください。私もまだそれに取り組んでいます。なぜ私はここにいるのですか?ご質問ありがとうございます。また、標準ライブラリもご覧ください。参考までに、シングルトンモジュールがあります。
これはかなり良いです。 https://www.youtube.com/watch?v=i4uiyWA8eFk