Apa yang class << selfdilakukan di Ruby ?
Apa yang class << selfdilakukan di Ruby ?
Jawaban:
Pertama, class << foosintaks membuka fookelas singleton (eigenclass). Ini memungkinkan Anda untuk mengkhususkan perilaku metode yang dipanggil pada objek tertentu.
a = 'foo'
class << a
def inspect
'"bar"'
end
end
a.inspect # => "bar"
a = 'foo' # new object, new singleton class
a.inspect # => "foo"
Sekarang, untuk menjawab pertanyaan: class << selfmembuka selfkelas singleton, sehingga metode dapat didefinisikan ulang untuk selfobjek saat ini (yang di dalam kelas atau badan modul adalah kelas atau modul itu sendiri ). Biasanya, ini digunakan untuk mendefinisikan metode kelas / modul ("statis"):
class String
class << self
def value_of obj
obj.to_s
end
end
end
String.value_of 42 # => "42"
Ini juga dapat ditulis sebagai steno:
class String
def self.value_of obj
obj.to_s
end
end
Atau bahkan lebih pendek:
def String.value_of obj
obj.to_s
end
Ketika di dalam definisi fungsi, selfmerujuk ke objek yang dipanggil fungsi. Dalam hal ini, class << selfbuka kelas tunggal untuk objek itu; satu kegunaannya adalah untuk mengimplementasikan mesin negara orang miskin:
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
Jadi, dalam contoh di atas, setiap contoh StateMachineExampletelah process_hookalias untuk process_state_1, namun catatan bagaimana di kedua, dapat mendefinisikan kembali process_hook(untuk selfsaja, yang tidak mempengaruhi lainnya StateMachineExamplecontoh) untuk process_state_2. Jadi, setiap kali penelepon memanggil processmetode (yang memanggil didefinisikan ulang process_hook), perilaku berubah tergantung pada keadaan apa itu.
class << self, untuk membuat metode kelas / modul. Saya mungkin akan memperluas penggunaan itu class << self, karena itu adalah penggunaan yang jauh lebih idiomatis.
a's singleton_classkarena a' kelas s (setelah mengubah inspect) adalah varian unik dari Stringkelas. Jika itu mengubah Stringkelas singleton itu akan mempengaruhi semua Stringcontoh lainnya . Yang lebih aneh lagi adalah bahwa jika nanti Anda membuka kembali Stringuntuk mendefinisikan ulang inspectmaka aakan tetap mengambil perubahan baru.
class << selfartinya lebih dari nilai selfyang diset sama dengan kelas singleton dalam ruang lingkup blok?
Saya menemukan penjelasan super sederhana tentang class << self, Eigenclassdan berbagai jenis metode.
Di Ruby, ada tiga jenis metode yang dapat diterapkan ke kelas:
Metode instance dan metode kelas hampir mirip dengan homonim mereka dalam bahasa pemrograman lain.
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
Cara lain untuk mengakses Eigenclass(yang mencakup metode tunggal) adalah dengan sintaks berikut ( class <<):
foo = Foo.new
class << foo
def a_singleton_method
puts "I am a singleton method"
end
end
sekarang Anda dapat mendefinisikan metode singleton selfyang merupakan kelas Fooitu sendiri dalam konteks ini:
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)untuk memeriksa.
Biasanya, metode instan adalah metode global. Itu berarti mereka tersedia dalam semua instance kelas di mana mereka didefinisikan. Sebaliknya, metode singleton diterapkan pada satu objek.
Ruby menyimpan metode dalam kelas dan semua metode harus dikaitkan dengan suatu kelas. Objek di mana metode singleton didefinisikan bukan kelas (itu adalah instance dari kelas). Jika hanya kelas yang dapat menyimpan metode, bagaimana suatu objek dapat menyimpan metode tunggal? Ketika metode singleton dibuat, Ruby secara otomatis membuat kelas anonim untuk menyimpan metode itu. Kelas anonim ini disebut metaclasses, juga dikenal sebagai kelas singleton atau eigenclasses. Metode singleton dikaitkan dengan metaclass yang, pada gilirannya, dikaitkan dengan objek di mana metode singleton didefinisikan.
Jika beberapa metode tunggal didefinisikan dalam satu objek, mereka semua disimpan dalam metaclass yang sama.
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'…
Dalam contoh di atas, kelas << z1 mengubah diri saat ini untuk menunjuk ke metaclass dari objek z1; kemudian, ia mendefinisikan metode say_hello dalam metaclass.
Kelas juga objek (turunan dari kelas yang disebut Kelas). Metode kelas tidak lebih dari metode tunggal yang terkait dengan objek kelas.
class Zabuton
class << self
def stuff
puts "Stuffing zabuton…"
end
end
end
Semua objek mungkin memiliki metaclasses. Itu berarti kelas juga dapat memiliki metaclasses. Dalam contoh di atas, kelas << self memodifikasi diri sehingga menunjuk ke metaclass dari kelas Zabuton. Ketika suatu metode didefinisikan tanpa penerima yang eksplisit (kelas / objek tempat metode tersebut akan didefinisikan), itu didefinisikan secara implisit dalam lingkup saat ini, yaitu, nilai saat ini dari diri. Oleh karena itu, metode barang didefinisikan dalam metaclass dari kelas Zabuton. Contoh di atas hanyalah cara lain untuk mendefinisikan metode kelas. IMHO, lebih baik menggunakan sintaks def self.my_new_clas_method untuk mendefinisikan metode kelas, karena itu membuat kode lebih mudah dimengerti. Contoh di atas disertakan sehingga kami memahami apa yang terjadi ketika kami menjumpai kelas << sintaks diri.
Info tambahan dapat ditemukan di posting ini tentang Ruby Classes .
class Hi
self #=> Hi
class << self #same as 'class << Hi'
self #=> #<Class:Hi>
self == Hi.singleton_class #=> true
end
end
[itu dibuat self == thing.singleton_class dalam konteks bloknya] .
hi = String.new
def hi.a
end
hi.class.instance_methods.include? :a #=> false
hi.singleton_class.instance_methods.include? :a #=> true
hiobjek mewarisi #methodsdari #singleton_class.instance_methodsdan kemudian dari #class.instance_methods.
Di sini kita memberikan hi's kelas tunggal metode contoh :a. Itu bisa dilakukan dengan kelas << hai sebagai gantinya.
hiIni #singleton_classsemua contoh metode hi's #classmemiliki, dan mungkin lagi ( :adi sini).
[contoh metode hal #class dan #singleton_class dapat diterapkan langsung ke hal ketika ruby melihat thing.a, ia pertama-tama mencari: definisi metode di thing.singleton_class.instance_methods dan kemudian di thing.class.instance_methods]
By the way - mereka memanggil kelas singleton objek == metaclass == eigenclass .
А metode tunggal adalah metode yang didefinisikan hanya untuk satu objek.
Contoh:
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
Metode Singleton untuk SomeClass
uji
Metode Singleton tentang test_obj
test_2
test_3
Bahkan jika Anda menulis ekstensi C untuk proyek Ruby Anda, hanya ada satu cara untuk mendefinisikan metode Modul.
rb_define_singleton_method
Saya tahu bisnis mandiri ini hanya membuka semua jenis pertanyaan lain sehingga Anda bisa melakukan yang lebih baik dengan mencari di setiap bagian.
Objek dulu.
foo = Object.new
Bisakah saya membuat metode untuk foo?
Tentu
def foo.hello
'hello'
end
Apa yang harus saya lakukan dengannya?
foo.hello
==>"hello"
Hanya objek lain.
foo.methods
Anda mendapatkan semua metode Objek plus yang baru.
def foo.self
self
end
foo.self
Hanya Obyek foo.
Cobalah untuk melihat apa yang terjadi jika Anda membuat foo dari Objek lain seperti Kelas dan Modul. Contoh-contoh dari semua jawaban bagus untuk dimainkan, tetapi Anda harus bekerja dengan ide atau konsep yang berbeda untuk benar-benar memahami apa yang terjadi dengan cara kode ditulis. Jadi sekarang Anda memiliki banyak persyaratan untuk dilihat.
Singleton, Class, Module, self, Object, dan Eigenclass dibesarkan tetapi Ruby tidak menyebut Model Object seperti itu. Ini lebih seperti Metaclass. Richard atau __why menunjukkan Anda ide di sini. http://viewsourcecode.org/why/hacking/seeingMetaclassesClearly.html Dan jika pukulan Anda pergi maka cobalah mencari Model Obyek Ruby dalam pencarian. Dua video yang saya tahu di YouTube adalah Dave Thomas dan Peter Cooper. Mereka mencoba menjelaskan konsep itu juga. Butuh waktu lama untuk mendapatkannya, jadi jangan khawatir. Saya masih mengerjakannya juga. Kenapa lagi saya di sini? Terima kasih atas pertanyaan anda Lihat juga perpustakaan standar. Ini memiliki Modul Singleton seperti halnya FYI.
Ini cukup bagus. https://www.youtube.com/watch?v=i4uiyWA8eFk