Ruby'de Range, bir başlangıç ve bitiş değeri arasındaki değerleri temsil eden nesnedir. İki noktalı 1..5 bitişi dahil eder (1, 2, 3, 4, 5), üç noktalı 1...5 bitişi hariç tutar (1, 2, 3, 4). Başlangıcı yazılmayan ..5 (beginless) ve sonu yazılmayan 1.. (endless) aralıklar da vardır. step ile adım adım gezer, cover? ve include? ile üyelik sorgular, case içinde ve dizi/string dilimlemede aralık kullanırsınız.
Bu yazıda aralık oluşturmayı, iki ve üç nokta farkını, açık uçlu aralıkları, step ve each ile gezinmeyi, cover? ile include? arasındaki ince farkı ve Ruby 4.0 ile gelen düzeltmeleri çalışan örneklerle anlatıyoruz. Serinin tamamı için Ruby öğrenme rehberine bakabilirsiniz.
İki nokta ve üç nokta: bitiş dahil mi?

Aralık literalini parantez içine almak iyi bir alışkanlıktır, çünkü .. operatörünün önceliği metot çağrısından düşüktür. 1..5.to_a yazarsanız Ruby önce 5.to_a çağırmaya çalışır. Aralığı Range.new ile de kurabilirsiniz; üçüncü argüman true ise bitiş hariç tutulur.
(1..5).to_a # => [1, 2, 3, 4, 5]
(1...5).to_a # => [1, 2, 3, 4]
("a".."e").to_a # => ["a", "b", "c", "d", "e"]
Range.new(1, 5, true) # => 1...5
(1...5).exclude_end? # => true
(1..5).size # => 5
(1...5).max # => 4
(1..5).frozen? # => true
begin
1..5.to_a
rescue NoMethodError => e
puts e.message # çıktı: undefined method 'to_a' for an instance of Integer
endRuby 3.0 NEWS dosyasına göre bütün Range nesneleri dondurulmuştur; bir aralığı değiştiremez, yalnızca yenisini oluşturabilirsiniz. Bir aralıkta yalnızca <=> ile karşılaştırılabilen değerler kullanılabilir; aralığın gezilebilmesi için ise başlangıç değerinin succ metodu olmalıdır. Integer, String ve Symbol bu koşulu sağlar, Float ve Time sağlamaz.
Başı veya sonu açık aralıklar
Endless (sonu açık) bir aralık başlangıçtan sonraki bütün değerleri, beginless (başı açık) bir aralık bitişe kadarki bütün değerleri kapsar. Dizi ve string dilimlemede çok kullanışlıdırlar: "ikinci elemandan sona kadar" ya da "baştan üçüncüye kadar" demenin kısa yoludur.
harfler = %w[a b c d e]
harfler[2..] # => ["c", "d", "e"]
harfler[..1] # => ["a", "b"]
harfler[...-1] # => ["a", "b", "c", "d"]
(1..).first(3) # => [1, 2, 3]
(..10).include?(-5) # => true
(1..).size # => Infinity
(1..).end # => nil
begin
(..5).each { |i| p i }
rescue TypeError => e
puts e.message # çıktı: can't iterate from NilClass
endSonu açık bir aralıkta each sonsuza kadar sürer; mutlaka break, first ya da take gibi bir sınır koyun. Başı açık bir aralık ise hiç gezilemez, çünkü nereden başlanacağı belli değildir. Sonsuz dizilerle güvenli çalışmanın yolu Enumerator ve lazy yazısında anlatılıyor.
Gezinme: each, step ve %
Range, Enumerable modülünü içerir; bu yüzden each, map, select, sum gibi bütün metotlar aralıklarda da çalışır. step(n) her n'inci değeri verir. Blok verilmezse ve değerler sayıysa step bir Enumerator::ArithmeticSequence döndürür; % operatörü bunun kısa yazımıdır.
(1..3).each { |i| puts "Adım #{i}" }
# çıktı: Adım 1
# çıktı: Adım 2
# çıktı: Adım 3
(0..10).step(3).to_a # => [0, 3, 6, 9]
(0..1).step(0.25).to_a # => [0.0, 0.25, 0.5, 0.75, 1.0]
(1..10).step(4) # => ((1..10).step(4))
((1..10) % 4).to_a # => [1, 5, 9]
(10..0).step(-5).to_a # => [10, 5, 0]
(10..0).to_a # => []
(1..100).sum # => 5050
(1..4).map { |i| i * 10 } # => [10, 20, 30, 40]Başlangıcı bitişinden büyük bir aralık (10..0) boştur ve each hiç çalışmaz. Geriye doğru saymak için negatif adımlı step ya da 10.downto(0) kullanın. Döngü yapılarının tamamı döngüler yazısında.
cover?, include? ve ===: üyelik sorgusu

cover? yalnızca karşılaştırma yapar: değer başlangıçtan büyük ya da eşit ve bitişten küçük (ya da dahilse eşit) mi? include? (diğer adı member?) sayısal aralıklarda cover? gibi davranır, ama sayısal olmayan aralıklarda değerin aralığın gerçekten bir elemanı olup olmadığına bakar. Fark en çok string aralıklarında görülür:
(1..10).include?(5.5) # => true
(1..10).cover?(5.5) # => true
("a".."z").include?("bb") # => false
("a".."z").cover?("bb") # => true
(1..10).cover?(2..4) # => true
(1...10).cover?(10) # => false
(1..10) === 7 # => true
ilk = Time.utc(2026, 1, 1)
son = Time.utc(2026, 12, 31)
(ilk..son).cover?(Time.utc(2026, 11, 7)) # => true"bb", sözlük sırasına göre "a" ile "z" arasındadır, bu yüzden cover? true der. Ama "a".."z" aralığını gezdiğinizde "bb" hiç üretilmez, bu yüzden include? false der. Tarih ve saat gibi gezilemeyen değerlerde de cover? kullanın.
case ifadesinde aralıklar
case/when, her dalı === ile dener ve Range#=== değerin aralıkta olup olmadığını söyler. Not aralıkları, yaş grupları ya da fiyat dilimleri bu yüzden çok okunaklı yazılır. Ondalıklı değerler gelebiliyorsa üç noktalı aralıklar sınırlarda boşluk bırakmaz: 70...85 84,5'i kapsar, 85'i bir sonraki dala bırakır.
def harf_notu(puan)
case puan
when 85..100 then "AA"
when 70...85 then "BA"
when 50...70 then "CC"
when 0...50 then "FF"
else "geçersiz"
end
end
harf_notu(92) # => "AA"
harf_notu(84.5) # => "BA"
harf_notu(85) # => "AA"
harf_notu(30) # => "FF"
harf_notu(120) # => "geçersiz"Koşul yapılarının diğer biçimleri if, unless ve case yazısında, aralıkları desen olarak kullanmak ise pattern matching yazısında anlatılıyor.
Dizi ve string dilimlemede aralıklar
Array#[] ve String#[] aralık kabul eder. Negatif değerler sondan sayar; 1..-2 "ikinci elemandan sondan ikinciye kadar" demektir. Bir step sonucu (aritmetik dizi) verirseniz dizilerde atlamalı dilim de alabilirsiniz.
metin = "Merhaba Dünya"
metin[0..6] # => "Merhaba"
metin[8..] # => "Dünya"
metin[-5..] # => "Dünya"
[10, 20, 30, 40, 50][1..-2] # => [20, 30, 40]
[10, 20, 30, 40, 50][(0..).step(2)] # => [10, 30, 50]Diziler ve string'ler için diğer dilimleme biçimleri Array yazısında ve String yazısında.
Aralık bilgilerini sorgulama: begin, end, first, last, minmax
begin ve end aralığı kurarken verdiğiniz değerleri olduğu gibi döndürür; üç noktalı bir aralıkta end hariç tutulan değerdir. first ve last ise gerçek elemanlara bakar ve sayı argümanıyla birden fazla eleman verir. min, max ve minmax aralığın uç değerlerini hesaplar. Üç noktalı bir aralığın en büyük elemanını bulmak yalnızca tam sayı bitişlerinde mümkündür; Float bitişte Ruby hata verir.
r = (3...8)
r.begin # => 3
r.end # => 8
r.first(2) # => [3, 4]
r.last(2) # => [6, 7]
r.minmax # => [3, 7]
r.to_a.size # => 5
(1.0..2.5).max # => 2.5
begin
(1.0...2.5).max
rescue TypeError => e
puts e.message # çıktı: cannot exclude non Integer end value
end
("a".."e").inspect # => "\"a\"..\"e\""
("a".."e").to_s # => "a..e"Son iki satır, inspect ile to_s arasındaki farkı gösterir: inspect uç değerleri kendi inspect biçimleriyle (tırnaklarıyla) yazar, to_s ise düz metin olarak birleştirir. Aralığı kullanıcıya gösterirken to_s, hata ayıklarken inspect daha açıklayıcıdır.
Ruby 4.0 ile gelen Range düzeltmeleri
Ruby 4.0 NEWS dosyası Range için üç madde listeler: Range#to_set artık sonsuz aralıkları kontrol ediyor, Range#overlap? sınırsız (unbounded) aralıkları doğru ele alıyor ve başı açık tam sayı aralıklarında Range#max davranışı düzeltildi. Ayrıca Set artık çekirdek sınıf olduğu için to_set için require gerekmez.
(1..4).to_set # => Set[1, 2, 3, 4]
begin
(1..).to_set
rescue RangeError => e
puts e.message # çıktı: cannot convert endless range to a set
end
(1..5).overlap?(5..8) # => true
(1...5).overlap?(5..8) # => false
(..5).overlap?(3..) # => true
(..5).max # => 5Set[1, 2, 3, 4] görünümü de Ruby 4.0 ile geldi; eski sürümler #<Set: {1, 2, 3, 4}> yazıyordu. Set için Ruby Set sınıfı yazısına bakın.
Yaygın hatalar

- Parantez unutmak:
1..5.eachya da1..5.to_aaralığa değil 5 sayısına metot çağırır.(1..5).eachyazın. - .. ile ... karıştırmak:
arr[0...arr.size]bütün diziyi verir,arr[0..arr.size]de verir ama niyeti bulanıklaştırır; sınırı dahil etmek istiyor musunuz, açıkça seçin. - Sonu açık aralıkta to_a veya each çağırmak:
(1..).to_abitmez;first(n)kullanın. - String aralıklarında include? beklemek: sıralama kontrolü istiyorsanız
cover?kullanın. - Ters aralıktan değer beklemek:
(5..1).to_aboştur;5.downto(1)ya da(5..1).step(-1)kullanın.
Sık Sorulan Sorular
size ile count arasında fark var mı?
size sayısal aralıklarda eleman sayısını hesaplar; sonu açıksa Infinity döner. count Enumerable'dan gelir, blok ya da değer de alabilir: (1..10).count(&:even?) sonucu 5.
Float aralığı gezilebilir mi?
each ile hayır, çünkü Float'ın succ metodu yoktur. Ama (0.0..1.0).step(0.1) gibi adım vererek gezebilir, cover? ve include? ile üyelik sorgulayabilirsiniz.
Kendi sınıfımın nesnelerini aralıkta kullanabilir miyim?
Evet. Belgelere göre sınıfınızın <=> metodunu tanımlaması aralık kurmak ve cover? kullanmak için yeterlidir. Aralığı each ile gezmek istiyorsanız bir sonraki değeri döndüren succ metodunu da tanımlamanız gerekir. Comparable modülünü eklemek, == ve diğer karşılaştırma operatörlerini <=> üzerinden kazandırır; ayrıntılar Comparable yazısında.
Range ile Array arasındaki fark nedir?
Aralık yalnızca iki ucu saklar, elemanları bellekte tutmaz; (1..1_000_000) küçük bir nesnedir. to_a çağırdığınızda bütün elemanlar bir diziye yazılır. Üyelik sorgusu ya da gezinme için çoğu zaman aralığın kendisi yeterlidir, diziye çevirmeniz gerekmez.
Bir aralığı değiştirebilir miyim?
Hayır. Range nesneleri dondurulmuştur; başlangıcı ya da bitişi farklı bir aralık için yeni bir nesne oluşturursunuz, örneğin (r.begin..r.end + 1).
Marka adları sahiplerine aittir. Bu yazı bağımsız bir teknik rehberdir; adı geçen kuruluşlarla bayilik veya ortaklık ilişkisi bulunduğu anlamına gelmez.
İlgili içerikler: Ruby öğrenme rehberi · Döngüler: while, until, each · if, unless ve case · Ruby Array metotları · Enumerable: map, select, reduce · Ruby Set sınıfı