Apa ini double-colon ::
? Misalnya Foo::Bar
.
Saya menemukan definisi :
Ini
::
adalah operator unary yang memungkinkan: konstanta, metode instance dan metode kelas yang didefinisikan dalam kelas atau modul, dapat diakses dari mana saja di luar kelas atau modul.
Apa gunanya ruang lingkup (pribadi, terlindungi) jika Anda bisa menggunakannya ::
untuk mengekspos sesuatu?
Jawaban:
::
pada dasarnya adalah operator resolusi namespace. Ini memungkinkan Anda untuk mengakses item dalam modul, atau item tingkat kelas di kelas. Misalnya, Anda memiliki pengaturan ini:Anda dapat mengakses
CONSTANT
dari luar modul sebagaiSomeModule::InnerModule::MyClass::CONSTANT
.Itu tidak memengaruhi metode instance yang didefinisikan pada kelas, karena Anda mengaksesnya dengan sintaks yang berbeda (titik
.
).Catatan yang relevan: Jika Anda ingin kembali ke namespace tingkat atas, lakukan ini: :: SomeModule - Benjamin Oakes
sumber
::
untuk resolusi namespace sepertistd::cout << "Hello World!";
::SomeModule
Contoh sederhana ini menggambarkannya:
Diambil dari http://www.tutorialspoint.com/ruby/ruby_operators.htm
sumber
::
Memungkinkan Anda mengakses konstanta, modul, atau kelas yang ditentukan di dalam kelas atau modul lain. Ini digunakan untuk menyediakan ruang nama sehingga metode dan nama kelas tidak bertentangan dengan kelas lain oleh penulis yang berbeda.Ketika Anda melihat
ActiveRecord::Base
di Rails itu berarti Rails memiliki sesuatu sepertiyaitu kelas yang disebut
Base
di dalam modulActiveRecord
yang kemudian dirujuk sebagaiActiveRecord::Base
(Anda dapat menemukan ini di sumber Rails di activerecord-nnn / lib / active_record / base.rb)Penggunaan umum :: adalah untuk mengakses konstanta yang didefinisikan dalam modul misalnya
The
::
operator tidak memungkinkan Anda untuk visibilitas memotong metode ditandai pribadi atau dilindungi.sumber
class MyClass < ActiveRecord::Base
, apakah itu berarti bahwa MyClass hanya mewarisi metode dari basis kelas dan bukan apa pun di dalam modul ActiveRecord?class Foo; Baz = 42; def self.Baz; "Baz method!"; end; end
(sangat valid)Foo::Baz # => 42
danFoo.Baz # => "Baz method!"
. Perhatikan bahwaFoo::Baz()
(dengan tanda kurung) juga akan memanggil metode.Di Ruby, semuanya terbuka dan semuanya dapat dimodifikasi dari tempat lain.
Jika Anda khawatir tentang fakta bahwa kelas dapat diubah dari luar "definisi kelas", maka Ruby mungkin bukan untuk Anda.
Di sisi lain, jika Anda frustrasi dengan kelas Java dikunci, maka Ruby mungkin adalah yang Anda cari.
sumber
attr_accessor
hanya membuat metode yang mengubah variabel. (Kemudian ada lagiinstance_eval
)instance_eval
. Tapi ada jugainstance_variable_get
daninstance_variable_set
. Ruby terlalu dinamis untuk kendala.Menambahkan ke jawaban sebelumnya, itu sah Ruby untuk digunakan
::
untuk mengakses metode contoh. Semua yang berikut ini valid:Sesuai praktik terbaik saya percaya hanya yang terakhir direkomendasikan.
sumber
Tidak, ini bukan untuk mengakses setiap metode, ini adalah operator "resolusi", yaitu, Anda menggunakannya untuk menyelesaikan ruang lingkup (atau lokasi yang dapat Anda katakan) dari simbol konstan / statis.
Sebagai contoh di baris pertama Anda, Rails menggunakannya untuk menemukan kelas Base di dalam ActiveRecord.Module, yang kedua digunakan untuk menemukan metode kelas (statis) dari kelas Rute, dll, dll.
Itu tidak digunakan untuk mengekspos apa pun, itu digunakan untuk "menemukan" barang-barang di sekitar lingkup Anda.
http://en.wikipedia.org/wiki/Scope_resolution_operator
sumber
Anehnya, semua 10 jawaban di sini mengatakan hal yang sama. '::' adalah operator resolusi namespace, dan ya itu benar. Tetapi ada satu gotcha yang harus Anda sadari tentang operator resolusi namespace ketika datang ke algoritma pencarian konstan . Sebagai Matz menggambarkan dalam bukunya, 'Bahasa Pemrograman Ruby', pencarian konstan memiliki beberapa langkah. Pertama, ia mencari konstanta dalam lingkup leksikal di mana konstanta direferensikan. Jika tidak menemukan konstanta dalam lingkup leksikal, maka ia akan mencari hierarki warisan . Karena algoritma pencarian konstan ini, di bawah ini kami mendapatkan hasil yang diharapkan:
Sementara F mewarisi dari E, modul B berada dalam ruang lingkup leksikal F. Akibatnya, instance F akan merujuk ke PI konstan yang didefinisikan dalam modul B. Sekarang jika modul B tidak mendefinisikan PI, maka instance F akan merujuk ke PI konstan didefinisikan dalam superclass E.
Tetapi bagaimana jika kita menggunakan modul '::' daripada bersarang? Apakah kita akan mendapatkan hasil yang sama? Tidak!
Dengan menggunakan operator resolusi namespace ketika mendefinisikan modul bersarang, modul dan kelas bersarang tidak lagi dalam lingkup leksikal dari modul luar mereka. Seperti yang Anda lihat di bawah, PI yang didefinisikan dalam A :: B tidak dalam lingkup leksikal A :: B :: C :: D dan dengan demikian kita mendapatkan konstanta yang tidak diinisialisasi ketika mencoba merujuk ke PI dalam metode instance get_pi:
sumber
Ini semua tentang mencegah definisi dari bentrok dengan kode lain yang terhubung ke proyek Anda. Itu berarti Anda dapat memisahkan hal-hal.
Misalnya Anda dapat memiliki satu metode yang disebut "run" di kode Anda dan Anda masih dapat memanggil metode Anda daripada metode "run" yang telah didefinisikan di beberapa perpustakaan lain yang telah Anda tautkan.
sumber
:: Digunakan untuk membuat ruang lingkup. Untuk mengakses Constant EATER dari 2 modul, kita perlu mengatur cakupan modul untuk mencapai konstanta
sumber
Ruby on rails digunakan
::
untuk resolusi namespace.Untuk menggunakannya:
Juga, penggunaan lainnya adalah: Saat menggunakan rute bersarang
OmniauthCallbacksController
didefinisikan di bawah pengguna.Dan dialihkan sebagai:
sumber