Darsliklar Ruby Modul va Mixin

Ruby Ruby Modul va Mixin

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 include orqali 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.