Apa yang class << self
dilakukan di Ruby ?
Apa yang class << self
dilakukan di Ruby ?
Jawaban:
Pertama, class << foo
sintaks membuka foo
kelas 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 << self
membuka self
kelas singleton, sehingga metode dapat didefinisikan ulang untuk self
objek 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, self
merujuk ke objek yang dipanggil fungsi. Dalam hal ini, class << self
buka 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 StateMachineExample
telah process_hook
alias untuk process_state_1
, namun catatan bagaimana di kedua, dapat mendefinisikan kembali process_hook
(untuk self
saja, yang tidak mempengaruhi lainnya StateMachineExample
contoh) untuk process_state_2
. Jadi, setiap kali penelepon memanggil process
metode (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_class
karena a
' kelas s (setelah mengubah inspect
) adalah varian unik dari String
kelas. Jika itu mengubah String
kelas singleton itu akan mempengaruhi semua String
contoh lainnya . Yang lebih aneh lagi adalah bahwa jika nanti Anda membuka kembali String
untuk mendefinisikan ulang inspect
maka a
akan tetap mengambil perubahan baru.
class << self
artinya lebih dari nilai self
yang diset sama dengan kelas singleton dalam ruang lingkup blok?
Saya menemukan penjelasan super sederhana tentang class << self
, Eigenclass
dan 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 self
yang merupakan kelas Foo
itu 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
hi
objek mewarisi #methods
dari #singleton_class.instance_methods
dan kemudian dari #class.instance_methods
.
Di sini kita memberikan hi
's kelas tunggal metode contoh :a
. Itu bisa dilakukan dengan kelas << hai sebagai gantinya.
hi
Ini #singleton_class
semua contoh metode hi
's #class
memiliki, dan mungkin lagi ( :a
di 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