Kata kunci module di Ruby memiliki dua peran besar, dan peran pertamanya adalah sebagai wadah nama. Topik ini membahas module sebagai namespace, yaitu ruang nama yang mengelompokkan konstanta di bawah satu nama, mulai dari pendefinisian dan pengaksesan dengan tanda ::, konstanta bersarang, pencegahan tabrakan nama, hingga perbedaan modul dari kelas. Setelah membacanya, konstanta program dapat ditata dalam hierarki yang rapi, dan risiko dua nama yang sama saling menimpa dapat dihindari.
Kata kunci module sebagai wadah nama#
Kata kunci module mendefinisikan sebuah modul, yaitu objek bertipe Module yang dapat menampung konstanta dan metode di bawah satu nama. Ketika program membesar, konstanta yang diletakkan bebas di tingkat atas mudah saling bercampur, sedangkan modul memberi setiap kelompok nilai sebuah alamat tersendiri. Modul sering dipilih sebagai wadah nilai-nilai yang melekat pada satu ranah, misalnya batas pembacaan sensor atau satuan pengukurannya.
Program berikut mendefinisikan modul Sensor yang menampung tiga konstanta, lalu membacanya kembali dengan tanda ::.
# Modul Sensor menjadi wadah konstanta milik stasiun cuaca.
module Sensor
BATAS_ATAS = 100
BATAS_BAWAH = -20
SATUAN = "derajat Celsius"
end
puts Sensor::BATAS_ATAS
puts Sensor::BATAS_BAWAH
puts Sensor::SATUAN
p Sensor.constants.sort100
-20
derajat Celsius
[:BATAS_ATAS, :BATAS_BAWAH, :SATUAN]Tanda titik dua ganda :: mengakses isi modul dari luar, sehingga Sensor::BATAS_ATAS dibaca sebagai konstanta BATAS_ATAS yang berada di dalam modul Sensor. Metode constants milik modul mendaftar seluruh konstanta yang dimiliki modul secara langsung, dan keluarannya menunjukkan ketiga nama itu tersimpan dalam satu wadah. Tanpa modul, ketiga nama tersebut berada di tingkat atas program dan wilayah kepemilikannya tidak terlihat dari namanya.
Modul juga boleh menampung metode, tetapi untuk peran namespace, isinya yang paling khas adalah konstanta dan modul bersarang. Konstanta yang dimasukkan sebaiknya benar-benar konstan selama program berjalan, misalnya batas alat ukur, faktor konversi, atau nama satuan, karena perubahan nilainya memicu peringatan, sebagaimana dijelaskan pada bagian Mencegah tabrakan nama. Dengan kebiasaan tersebut, kehadiran sebuah modul pada kode lain menjadi petunjuk bahwa di dalamnya terdapat kumpulan nilai yang saling berkaitan dan bermakna pada satu ranah.
Konstanta bersarang dan tanda ::#
Modul dapat didefinisikan di dalam modul lain, dan konstanta yang dihasilkan tersusun dalam hierarki sebagaimana direktori di dalam direktori. Nama modul yang berada di dalam badan modul lain juga merupakan konstanta, karena namanya diawali huruf kapital dan nilainya adalah objek Module. Sifat inilah yang membuat pembacaan Sensor::Kalibrasi::FAKTOR dapat dilakukan dari kiri ke kanan, yaitu turun satu tingkat pada setiap tanda ::.
# Modul dapat bersarang, sehingga konstanta tersusun dalam hierarki.
module Sensor
module Kalibrasi
FAKTOR = 1.05
module Rentang
MINIMUM = 0
MAKSIMUM = 50
end
end
end
puts Sensor::Kalibrasi::FAKTOR
puts Sensor::Kalibrasi::Rentang::MAKSIMUM
p Sensor::Kalibrasi.constants.sort1.05
50
[:FAKTOR, :Rentang]Baris terakhir keluaran memperlihatkan isi modul Sensor::Kalibrasi, yaitu konstanta FAKTOR dan modul bersarang bernama Rentang, dan keduanya terdaftar sebagai anggota tingkat pertama Kalibrasi. Diagram berikut merangkum hierarki yang terbentuk dari kedua contoh program, beserta tiga konstanta lain pada tingkat terluar.
Mencegah tabrakan nama#
Namespace terutama digunakan agar dua nama yang sama tidak saling menimpa. Dua bagian program dapat memiliki konstanta bernama sama, misalnya BATAS, dengan maksud yang berbeda. Apabila keduanya diletakkan di tingkat atas, penugasan kedua menimpa nilai pertama dan memunculkan peringatan interpreter. Membungkus setiap nilai dalam modulnya masing-masing membuat kedua konstanta dapat berdampingan tanpa saling mengganggu.
# Dua modul boleh memakai nama konstanta yang sama tanpa saling menimpa.
module SensorSuhu
BATAS = 100
end
module SensorKelembapan
BATAS = 80
end
puts SensorSuhu::BATAS
puts SensorKelembapan::BATAS
begin
puts BATAS
rescue NameError => e
puts e.class
puts e.message
end100
80
NameError
uninitialized constant BATASDua konstanta BATAS kini memiliki alamat penuh yang berbeda, yaitu SensorSuhu::BATAS bernilai 100 dan SensorKelembapan::BATAS bernilai 80. Baris terakhir program sengaja mencoba membaca nama BATAS langsung dari tingkat atas, dan Ruby menjawab dengan NameError karena nama itu memang tidak terdaftar pada tingkat atas. Kesalahan semacam ini lazim muncul ketika konstanta dipindahkan ke dalam modul, sedangkan baris lain masih membacanya dengan alamat lama, sehingga pesan errornya justru menunjukkan letak baris yang perlu diperbarui.
Module bukan kelas#
Modul menyerupai kelas karena keduanya menampung nama dan metode, tetapi modul tidak dapat diinstansiasi. Tidak ada objek baru yang dibuat dari sebuah modul, karena modul tidak menyediakan metode new. Program berikut memanggil new pada modul Sensor dan menangkap errornya untuk membuktikan perilaku itu.
# Modul tidak bisa diinstansiasi karena tidak menyediakan metode new.
module Sensor
BATAS = 100
end
begin
Sensor.new
rescue NoMethodError => e
puts e.class
puts e.message
end
puts Sensor.class
p Class.superclassNoMethodError
undefined method 'new' for module Sensor
Module
ModulePesan error menyatakan penyebabnya secara langsung, yaitu metode new memang tidak dimiliki modul. Dua baris terakhir melengkapi gambaran tersebut, yaitu Sensor.class mengembalikan Module dan Class.superclass juga mengembalikan Module, sehingga kelas pada dasarnya adalah modul yang ditambah kemampuan membuat instans. Konsisten dengan sifat itu, Ruby juga menolak sebuah modul dijadikan kelas induk pada pewarisan, karena rantai pewarisan memang harus berupa kelas. Pemilihan antara keduanya dapat didasarkan pada pertanyaan sederhana, yaitu apakah kelompok nilai itu perlu dibuat sebagai objek. Apabila tidak, modul adalah wadah yang tepat, sedangkan kemampuannya menampung metode menjadi dasar penggunaan modul sebagai mixin, yaitu mekanisme berbagi metode antarkelas.
Ringkasan#
- Kata kunci
modulemendefinisikan objek Module yang menampung konstanta di bawah satu nama, dan tanda::mengakses isinya. - Modul dapat bersarang sehingga alamat konstanta bertingkat, misalnya
Sensor::Kalibrasi::FAKTOR, dan nama modul bersarang juga berupa konstanta. - Dua modul boleh menggunakan nama konstanta yang sama tanpa saling menimpa, sedangkan pembacaan dengan alamat yang salah memunculkan NameError.
- Modul tidak dapat diinstansiasi karena tidak memiliki metode
new, danClass.superclassmengembalikan Module.
Referensi#
- Module — Ruby
— Dokumentasi kelas Module, termasuk metode
constantsdan peran modul sebagai wadah nama. - Assignment — Ruby — Bagian local variables dan constants menjelaskan penamaan serta lingkup konstanta.