Modul (Module) — Ruby’ning meros’dan tashqari kod qayta ishlatish vositasi. Sinfdan farqi: moduldan obyekt yaratib bo’lmaydi (.new yo’q). Uning asosiy vazifasi — metodlar to’plamini bir nechta, bir-biriga aloqasi bo’lmagan sinflarga qorishtirish (mixin).
Mixin — modulni
includeorqali sinfga qo’shish, natijada sinf modul metodlarini xuddi o’zinikidek meros oladi. Ruby’da bitta sinf faqat bitta sinfdan meros ola oladi, lekin istagancha modulni “aralashtira” oladi — bu ko’p tillardagi “ko’p marotaba meros”ning Ruby’dagi xavfsiz muqobili.
Modul yaratish va include qilish
Modul module kalit so’zi bilan e’lon qilinadi, sinfga esa include orqali qo’shiladi:
module Salomlashuvchi
def salom_ayt
puts "Salom, men #{self.class}man!"
end
end
class Talaba
include Salomlashuvchi
end
class Oqituvchi
include Salomlashuvchi
end
Talaba.new.salom_ayt
Oqituvchi.new.salom_ayt
Salom, men Talabaman!
Salom, men Oqituvchiman!
Talaba va Oqituvchi — bir-biriga aloqasi yo’q, umumiy ota sinfga ega emas ikkala sinf ham, lekin ikkalasi ham Salomlashuvchi modulidan salom_ayt metodini oldi. Bu — merosdan farqli, “bu — shu turdan” emas, “bu — shu qobiliyatga ega” munosabati.
Bir nechta modulni birlashtirish
Sinf istagancha modulni bir vaqtda include qila oladi — bu Ruby’ning “ko’p marotaba meros” o’rniga taklif qiladigan yechimi:
module Suzuvchi
def suz
puts "Suzyapman"
end
end
module Yuruvchi
def yur
puts "Yuryapman"
end
end
class Odam
include Suzuvchi
include Yuruvchi
end
o = Odam.new
o.suz
o.yur
Suzyapman
Yuryapman
Odam faqat bitta sinfdan meros ola olardi, ammo ikkita moduldan qobiliyat oldi. Har bir modul — mustaqil, qayta ishlatiladigan xatti-harakat bloki.
Comparable — standart kutubxonaning tayyor mixin’i
Ruby standart kutubxonasi Comparable moduli bilan keladi: siz faqat <=> metodini yozasiz, u esa <, >, ==, between? kabi metodlarni bepul beradi:
class Mahsulot
include Comparable
attr_reader :narx
def initialize(nomi, narx)
@nomi = nomi
@narx = narx
end
def <=>(boshqa)
narx <=> boshqa.narx
end
end
arzon = Mahsulot.new("Quloqchin", 80000)
qimmat = Mahsulot.new("Noutbuk", 9000000)
puts arzon < qimmat
puts qimmat > arzon
puts arzon.between?(Mahsulot.new("Eng arzon", 1000), qimmat)
true
true
true
Biz faqat bitta metod — <=> (operatorlar darsida ko’rgan spaceship operatori) — yozdik. Comparable moduli shu bittasiga tayanib, qolgan barcha solishtirish metodlarini avtomatik hosil qildi. Bu mixin’ning haqiqiy kuchi: bir joyda mantiq yozilsa, ko’p imkoniyat ochiladi.
Modul — nomlar maydoni (namespace) sifatida
Modulning ikkinchi vazifasi — bog’liq sinf va metodlarni nom to’qnashuvidan himoyalash uchun guruhlash:
module UzbekDevs
class Kurs
def initialize(nomi)
@nomi = nomi
end
def nomi
@nomi
end
end
end
kurs = UzbekDevs::Kurs.new("Ruby asoslari")
puts kurs.nomi
Ruby asoslari
UzbekDevs::Kurs — ikki nuqta ikkitasi (::) modul ichidagi sinfga murojaat qiladi. Katta loyihalarda bu, masalan, ikkita turli kutubxonadagi bir xil nomli Kurs sinflarini bir-biridan ajratib turadi.