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).

Mixinmodulni 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.