Range — boshlanish va tugash qiymati orasidagi barcha qiymatlarni ifodalovchi klass. Massivdek har bir elementni alohida yozish shart emas — faqat chegaralarni ko’rsatish yetarli.
Range —
boshlanish..tugashyokiboshlanish...tugashshaklida yoziladigan, ketma-ket qiymatlar oralig’ini ifodalovchi klass. Ikki nuqta oxirgi qiymatni qamraydi, uch nuqta esa qamramaydi.
Qamrovchi va qamramaydigan oraliq
Ikki nuqta (..) va uch nuqta (...) orasidagi farq — Range’dagi eng muhim nozik jihat:
qamrovchi = (1..5)
qamramaydigan = (1...5)
puts qamrovchi.to_a.inspect
puts qamramaydigan.to_a.inspect
[1, 2, 3, 4, 5]
[1, 2, 3, 4]
1..5 — 5 ni ham o’z ichiga oladi (qamrovchi). 1...5 — 5 gacha, lekin 5siz (qamramaydigan). Bu farqni chalkashtirish siklda “off-by-one” xatolarga olib keladigan eng keng tarqalgan sabablardan biri.
Range’ni sikl va shartda ishlatish
Range o’zi ustida to’g’ridan-to’g’ri iteratsiya qilinishi va shart tekshirishda ishlatilishi mumkin:
(1..5).each { |son| print son, " " }
puts
yosh = 26
puts (18..65).include?(yosh)
puts (18..65).cover?(yosh)
1 2 3 4 5
true
true
each — har bir qiymat ustida amal bajaradi. include? va cover? qiymat oraliqda bor-yo’qligini tekshiradi — sonlar uchun ikkalasi bir xil ishlaydi, lekin cover? faqat chegaralarni solishtirgani uchun tezroq.
Harflar oralig’i
Range faqat sonlar bilan emas, ketma-ket qiymat bera oladigan har qanday tur (masalan, harflar) bilan ham ishlaydi:
harflar = ("a".."e")
puts harflar.to_a.inspect
["a", "b", "c", "d", "e"]
Ruby harflarni alifbo tartibida ketma-ket biladi, shuning uchun "a".."e" mantiqan 1..5 bilan bir xil tarzda ishlaydi.
Massiv kesimida Range
Oldingi darsda ko’rgan massiv kesish (slicing) amalida Range aynan shu klass edi:
sonlar = [10, 20, 30, 40, 50]
puts sonlar[1..3].inspect
puts sonlar[(1...3)].inspect
[20, 30, 40]
[20, 30]
[1..3] — 1 dan 3-indeksgacha (qamrab olib), [1...3] esa 3-indeksni qamramaydi. Range’ning ikki shakli shu yerda ham xuddi shu mantiq bilan ishlaydi.