Giriş
Programlama dillerinde operatörler, değerler üzerinde çeşitli işlemler yapmak için kullanılan sembollerdir. Ruby de bu konuda zengin bir operatör setine sahiptir. Bu operatörler, değişkenlere değer atamaktan, matematiksel hesaplamalar yapmaya, koşulları kontrol etmeye ve bit düzeyinde işlemlere kadar geniş bir yelpazede kullanılır. Bu yazıda, Ruby'deki başlıca operatör türlerini detaylı örneklerle inceleyeceğiz.
1. Aritmetik Operatörler
Bu operatörler, sayısal değerler üzerinde temel matematiksel işlemleri gerçekleştirmek için kullanılır.
2. Karşılaştırma Operatörleri
Bu operatörler, iki değeri karşılaştırmak ve bir boolean (doğru/yanlış) sonuç döndürmek için kullanılır.
3. Atama Operatörleri
Bu operatörler, bir değişkene değer atamak için kullanılır. Genellikle aritmetik operatörlerle birlikte kısayol olarak kullanılırlar.
4. Mantıksal Operatörler
Bu operatörler, birden fazla koşulu birleştirmek veya bir koşulun tersini almak için kullanılır. Ruby'de hem sembolik (`&&`, `||`, `!`) hem de anahtar kelime (`and`, `or`, `not`) mantıksal operatörler bulunur. Sembolik olanlar daha yüksek önceliğe sahiptir.
5. Bitwise Operatörler
Bu operatörler, sayıların ikili (binary) gösterimi üzerinde bit düzeyinde işlemler yapmak için kullanılır. Genellikle düşük seviyeli programlamada veya performans optimizasyonunda kullanılırlar.
6. Aralık Operatörleri
Ruby'de, bir dizi veya aralık tanımlamak için özel operatörler bulunur.
7. Üçlü (Ternary) Operatör
Bu operatör, kısa bir if-else ifadesi yazmak için kullanılır.
Sözdizimi: koşul ? doğru_ise_değer : yanlış_ise_değer
8. defined? Operatörü
defined? operatörü, bir ifadenin tanımlı olup olmadığını ve türünü kontrol eder. Tanımlıysa bir dize döndürür, aksi takdirde nil döndürür.
9. Paralel Atama
Ruby, birden fazla değişkene tek bir satırda değer atama veya değişkenlerin değerlerini değiştirme imkanı sunar. Bu, özellikle takas (swap) işlemleri için çok kullanışlıdır.
10. Özel Operatörler ve Metotlar
Ruby'de birçok operatör aslında birer metottur ve sınıflar içinde yeniden tanımlanabilir (operator overloading). Örneğin, + operatörü aslında Numeric sınıfında bir metot olarak tanımlıdır. Bu esneklik sayesinde kendi sınıflarınız için operatörlerin davranışını değiştirebilirsiniz.
Ruby Operatörleri Resmi Dokümantasyonu adresinden daha fazla bilgi edinebilirsiniz.
Operatör Önceliği
Bir ifadede birden fazla operatör kullanıldığında, Ruby belirli bir öncelik sırasına göre işlem yapar. Tıpkı matematikteki işlem önceliği (parantez, çarpma/bölme, toplama/çıkarma) gibi. En yüksek önceliğe sahip olanlar önce değerlendirilir. Eğer öncelik aynıysa, genellikle soldan sağa doğru işlem yapılır. Parantezler () kullanarak bu varsayılan önceliği değiştirebilirsiniz. Örneğin, mantıksal operatörlerde `&&` ve `||` anahtar kelimelerden (`and`, `or`) daha yüksek önceliğe sahiptir.
Sonuç
Ruby'deki operatörler, programcıya verimli ve okunabilir kod yazma konusunda büyük bir esneklik sunar. Her operatörün amacını ve kullanımını anlamak, daha sağlam ve hatasız uygulamalar geliştirmenize yardımcı olacaktır. Bu zengin operatör seti sayesinde, karmaşık algoritmaları bile kısa ve anlaşılır bir şekilde ifade edebilirsiniz.
Programlama dillerinde operatörler, değerler üzerinde çeşitli işlemler yapmak için kullanılan sembollerdir. Ruby de bu konuda zengin bir operatör setine sahiptir. Bu operatörler, değişkenlere değer atamaktan, matematiksel hesaplamalar yapmaya, koşulları kontrol etmeye ve bit düzeyinde işlemlere kadar geniş bir yelpazede kullanılır. Bu yazıda, Ruby'deki başlıca operatör türlerini detaylı örneklerle inceleyeceğiz.
1. Aritmetik Operatörler
Bu operatörler, sayısal değerler üzerinde temel matematiksel işlemleri gerçekleştirmek için kullanılır.
- + (Toplama): İki sayıyı toplar.
- - (Çıkarma): Bir sayıdan diğerini çıkarır.
- * (Çarpma): İki sayıyı çarpar.
- / (Bölme): Bir sayıyı diğerine böler. Tam sayı bölmesinde sonuç da tam sayı olur.
- % (Modülüs): Bölme işleminden kalanı verir.
- ** (Üs alma): Bir sayının üssünü alır.
Kod:
a = 10
b = 3
puts "Toplama (a + b): \#{a + b}" # Sonuç: 13
puts "Çıkarma (a - b): \#{a - b}" # Sonuç: 7
puts "Çarpma (a * b): \#{a * b}" # Sonuç: 30
puts "Bölme (a / b): \#{a / b}" # Sonuç: 3 (Tam sayı bölmesi)
puts "Modülüs (a % b): \#{a % b}" # Sonuç: 1
puts "Üs alma (a ** b): \#{a ** b}" # Sonuç: 1000
2. Karşılaştırma Operatörleri
Bu operatörler, iki değeri karşılaştırmak ve bir boolean (doğru/yanlış) sonuç döndürmek için kullanılır.
- == (Eşit mi?): İki değerin eşit olup olmadığını kontrol eder.
- != veya <> (Eşit değil mi?): İki değerin eşit olup olmadığını kontrol eder, eşit değilse doğru döndürür.
- > (Büyük mü?): Sol operandın sağ operanddan büyük olup olmadığını kontrol eder.
- < (Küçük mü?): Sol operandın sağ operanddan küçük olup olmadığını kontrol eder.
- >= (Büyük veya eşit mi?): Sol operandın sağ operanddan büyük veya eşit olup olmadığını kontrol eder.
- <= (Küçük veya eşit mi?): Sol operandın sağ operanddan küçük veya eşit olup olmadığını kontrol eder.
- <=> (Spaceship Operatörü): İki değeri karşılaştırır ve üç durumdan birini döndürür: -1 (sol küçükse), 0 (eşitse), 1 (sol büyükse). Özellikle sıralama algoritmalarında kullanışlıdır.
- === (Case Eşitliği): Case ifadelerinde ve Regex desen eşleştirmelerinde kullanılır. Daha esnek bir eşitlik kontrolüdür.
Kod:
x = 20
y = 15
z = 20
puts "x == y: \#{x == y}" # Sonuç: false
puts "x == z: \#{x == z}" # Sonuç: true
puts "x != y: \#{x != y}" # Sonuç: true
puts "x > y: \#{x > y}" # Sonuç: true
puts "x < y: \#{x < y}" # Sonuç: false
puts "x >= z: \#{x >= z}" # Sonuç: true
puts "y <= z: \#{y <= z}" # Sonuç: true
puts "Spaceship (x <=> y): \#{x <=> y}" # Sonuç: 1
puts "Spaceship (y <=> x): \#{y <=> x}" # Sonuç: -1
puts "Spaceship (x <=> z): \#{x <=> z}" # Sonuç: 0
case 5
when 1..10 then puts "Sayı 1-10 aralığında (=== operatörü)"
end # Sonuç: Sayı 1-10 aralığında (=== operatörü)
case "Merhaba"
when /Mer/ then puts "Metin 'Mer' içeriyor"
end # Sonuç: Metin 'Mer' içeriyor
3. Atama Operatörleri
Bu operatörler, bir değişkene değer atamak için kullanılır. Genellikle aritmetik operatörlerle birlikte kısayol olarak kullanılırlar.
- = (Basit Atama): Sağdaki değeri soldaki değişkene atar.
- += (Topla ve Ata): Değişkene bir değer ekler ve sonucu değişkene atar. (örn. `a = a + b` yerine `a += b`)
- -= (Çıkar ve Ata): Değişkenden bir değer çıkarır ve sonucu değişkene atar.
- *= (Çarp ve Ata): Değişkeni bir değerle çarpar ve sonucu değişkene atar.
- /= (Böl ve Ata): Değişkeni bir değere böler ve sonucu değişkene atar.
- %= (Modülüs ve Ata): Değişkenin modülüsünü alır ve sonucu değişkene atar.
- **= (Üs al ve Ata): Değişkenin üssünü alır ve sonucu değişkene atar.
Kod:
deger = 10
puts "Başlangıç değeri: \#{deger}" # Sonuç: 10
deger += 5
puts "deger += 5: \#{deger}" # Sonuç: 15
deger -= 3
puts "deger -= 3: \#{deger}" # Sonuç: 12
deger *= 2
puts "deger *= 2: \#{deger}" # Sonuç: 24
deger /= 4
puts "deger /= 4: \#{deger}" # Sonuç: 6
deger %= 5
puts "deger %= 5: \#{deger}" # Sonuç: 1
deger **= 3
puts "deger **= 3: \#{deger}" # Sonuç: 1
4. Mantıksal Operatörler
Bu operatörler, birden fazla koşulu birleştirmek veya bir koşulun tersini almak için kullanılır. Ruby'de hem sembolik (`&&`, `||`, `!`) hem de anahtar kelime (`and`, `or`, `not`) mantıksal operatörler bulunur. Sembolik olanlar daha yüksek önceliğe sahiptir.
- && veya and (VE): Her iki koşul da doğruysa doğru döndürür.
- || veya or (VEYA): Koşullardan en az biri doğruysa doğru döndürür.
- ! veya not (DEĞİL): Bir koşulun mantıksal tersini döndürür.
Kod:
yas = 25
ehliyet_var_mi = true
# && (VE) operatörü
if yas >= 18 && ehliyet_var_mi
puts "Sürüş izni verilebilir (&&)"
else
puts "Sürüş izni verilemez (&&)"
end # Sonuç: Sürüş izni verilebilir (&&)
# || (VEYA) operatörü
if yas < 18 || !ehliyet_var_mi
puts "Bazı koşullar eksik (||"
else
puts "Tüm koşullar uygun (||"
end # Sonuç: Tüm koşullar uygun (||
# ! (DEĞİL) operatörü
if !(yas < 18)
puts "Yaş 18'den küçük değil (!)"
end # Sonuç: Yaş 18'den küçük değil (!)
# 'and' ve 'or' örnekleri (daha düşük öncelik)
result = (true and false)
puts "true and false: \#{result}" # Sonuç: false
result = (true or false)
puts "true or false: \#{result}" # Sonuç: true
result = (not true)
puts "not true: \#{result}" # Sonuç: false
5. Bitwise Operatörler
Bu operatörler, sayıların ikili (binary) gösterimi üzerinde bit düzeyinde işlemler yapmak için kullanılır. Genellikle düşük seviyeli programlamada veya performans optimizasyonunda kullanılırlar.
- & (Bitwise AND): Her iki bitte de 1 varsa sonuç 1 olur.
- | (Bitwise OR): Bitlerden en az biri 1 ise sonuç 1 olur.
- ^ (Bitwise XOR): Bitler farklıysa sonuç 1 olur.
- ~ (Bitwise NOT): Bitleri tersine çevirir (0'ı 1, 1'i 0 yapar).
- << (Sola Kaydırma): Bitleri sola kaydırır, sağdan sıfır ekler. Her kaydırma, sayıyı 2 ile çarpmak gibidir.
- >> (Sağa Kaydırma): Bitleri sağa kaydırır, soldan sıfır ekler. Her kaydırma, sayıyı 2'ye bölmek gibidir.
Kod:
a = 5 # İkili: 0101
b = 3 # İkili: 0011
puts "Bitwise AND (a & b): \#{a & b}" # Sonuç: 1 (0001)
puts "Bitwise OR (a | b): \#{a | b}" # Sonuç: 7 (0111)
puts "Bitwise XOR (a ^ b): \#{a ^ b}" # Sonuç: 6 (0110)
puts "Bitwise NOT (~a): \#{~a}" # Sonuç: -6 (2'nin tümleyeni)
puts "Left Shift (a << 1): \#{a << 1}" # Sonuç: 10 (1010)
puts "Right Shift (a >> 1): \#{a >> 1}" # Sonuç: 2 (0010)
Bitwise NOT operatörü (`~`) biraz yanıltıcı olabilir. Ruby'de sayılar sabit boyutlu değildir ve 2'nin tümleyeni gösterimi kullanılır. Bu nedenle `~5` beklediğiniz gibi `10` değil, `-6` çıkar.
6. Aralık Operatörleri
Ruby'de, bir dizi veya aralık tanımlamak için özel operatörler bulunur.
- .. (İki nokta): Başlangıç ve bitiş değerlerini içeren bir aralık oluşturur (dahil).
- ... (Üç nokta): Başlangıç değerini içeren ancak bitiş değerini içermeyen bir aralık oluşturur (hariç).
Kod:
aralik1 = 1..5
puts "1..5 aralığı: \#{aralik1.to_a}" # Sonuç: [1, 2, 3, 4, 5]
aralik2 = 1...5
puts "1...5 aralığı: \#{aralik2.to_a}" # Sonuç: [1, 2, 3, 4]
# Aralıklar case ifadelerinde de kullanılabilir.
sayi = 7
case sayi
when 1..10 then puts "Sayı 1 ile 10 arasında (dahil)"
else puts "Sayı aralık dışında"
end # Sonuç: Sayı 1 ile 10 arasında (dahil)
7. Üçlü (Ternary) Operatör
Bu operatör, kısa bir if-else ifadesi yazmak için kullanılır.
Sözdizimi: koşul ? doğru_ise_değer : yanlış_ise_değer
Kod:
yas = 17
durum = (yas >= 18) ? "Yetişkin" : "Çocuk"
puts "Durum: \#{durum}" # Sonuç: Çocuk
yas = 20
durum = (yas >= 18) ? "Yetişkin" : "Çocuk"
puts "Durum: \#{durum}" # Sonuç: Yetişkin
8. defined? Operatörü
defined? operatörü, bir ifadenin tanımlı olup olmadığını ve türünü kontrol eder. Tanımlıysa bir dize döndürür, aksi takdirde nil döndürür.
Kod:
a = 10
b = nil
puts "defined?(a): \#{defined?(a)}" # Sonuç: local-variable
puts "defined?(b): \#{defined?(b)}" # Sonuç: local-variable
puts "defined?(c): \#{defined?(c)}" # Sonuç: nil
puts "defined?(puts): \#{defined?(puts)}" # Sonuç: method
puts "defined?($_): \#{defined?($_)}" # Sonuç: global-variable
9. Paralel Atama
Ruby, birden fazla değişkene tek bir satırda değer atama veya değişkenlerin değerlerini değiştirme imkanı sunar. Bu, özellikle takas (swap) işlemleri için çok kullanışlıdır.
Kod:
x, y = 10, 20
puts "Başlangıç: x=\#{x}, y=\#{y}" # Sonuç: Başlangıç: x=10, y=20
# Değerleri takas etme
x, y = y, x
puts "Takas sonrası: x=\#{x}, y=\#{y}" # Sonuç: Takas sonrası: x=20, y=10
# Çoklu atama
a, b, c = 1, 2, 3
puts "Çoklu atama: a=\#{a}, b=\#{b}, c=\#{c}" # Sonuç: Çoklu atama: a=1, b=2, c=3
10. Özel Operatörler ve Metotlar
Ruby'de birçok operatör aslında birer metottur ve sınıflar içinde yeniden tanımlanabilir (operator overloading). Örneğin, + operatörü aslında Numeric sınıfında bir metot olarak tanımlıdır. Bu esneklik sayesinde kendi sınıflarınız için operatörlerin davranışını değiştirebilirsiniz.
Ruby Operatörleri Resmi Dokümantasyonu adresinden daha fazla bilgi edinebilirsiniz.
Operatör Önceliği
Bir ifadede birden fazla operatör kullanıldığında, Ruby belirli bir öncelik sırasına göre işlem yapar. Tıpkı matematikteki işlem önceliği (parantez, çarpma/bölme, toplama/çıkarma) gibi. En yüksek önceliğe sahip olanlar önce değerlendirilir. Eğer öncelik aynıysa, genellikle soldan sağa doğru işlem yapılır. Parantezler () kullanarak bu varsayılan önceliği değiştirebilirsiniz. Örneğin, mantıksal operatörlerde `&&` ve `||` anahtar kelimelerden (`and`, `or`) daha yüksek önceliğe sahiptir.
Kod:
# Öncelik örneği
sonuc = 10 + 5 * 2 # Önce çarpma (5*2=10), sonra toplama (10+10=20)
puts "10 + 5 * 2 = \#{sonuc}" # Sonuç: 20
sonuc = (10 + 5) * 2 # Önce parantez içi (10+5=15), sonra çarpma (15*2=30)
puts "(10 + 5) * 2 = \#{sonuc}" # Sonuç: 30
# Mantıksal öncelik
a = true
b = false
c = true
# 'and' 'or' sembolik operatörlerden daha düşük öncelikli
puts "a and b or c: \#{a and b or c}" # (a and b) or c => (true and false) or true => false or true => true
puts "(a and b) or c: \#{(a and b) or c}" # Sonuç: true (aynı)
# && || önceliği
puts "a && b || c: \#{a && b || c}" # (a && b) || c => (true && false) || true => false || true => true
puts "(a && b) || c: \#{(a && b) || c}" # Sonuç: true (aynı)
Sonuç
Ruby'deki operatörler, programcıya verimli ve okunabilir kod yazma konusunda büyük bir esneklik sunar. Her operatörün amacını ve kullanımını anlamak, daha sağlam ve hatasız uygulamalar geliştirmenize yardımcı olacaktır. Bu zengin operatör seti sayesinde, karmaşık algoritmaları bile kısa ve anlaşılır bir şekilde ifade edebilirsiniz.