Ruby/Söz Dizimi/Kontrol Yapıları

←Operatörler | Metod Çağrıları→


Kontrol Yapıları

düzenle

Koşullu Dallanmalar

düzenle

Ruby program akışını koşullu dallanmalar kullanarak kontrol edebilir. Bir koşullu dallanma , bir test ifadesinin sonucunu alır ve sonucun doğru (true) ya da yanlış (false) olmasına göre bir blok program çalıştırır. Eğer test ifadesi sonucu false veya nil ise yanlış sonucun bloğu çalışır geri kalan tüm olasılıklar doğru sonuç olarak değerlendirilir. Yani sıfır değeri bile doğru olarak değerlendirilir. Diğer birçok programlama dillerinde sıfır, yanlış sonuç olarak değerlendirilir.

Birçok programlama dilinde koşullu dallanmalar deyimlerdir ve hangi kodun işleneceğini karar verirler. Ama kendileri bir değer dönmezler. Ruby'de koşullu dallanmalar aynı zamanda işlemdirler. Diğer işlemler gibi değerleri işlerler. Örneğin if işlemi sadece koda karar vermez aynı zamanda bir değer döner. Mesela aşağıdaki if işlemi 3 değerini geri döner:

if true
    3
end

yani şöyle denersek:

a = if true
    3
end
puts a    #=> 3


Ruby'nin koşullu dallanmaları aşağıda açıklanmıştır.


if ifadesi

düzenle

Örnekler:

a = 5
if a == 4
    a = 7
end
print a   # if bloğu işletilmediği için 5 yazacaktır


Ayrıca eğer then kullanırsanız if işlemcisi ve kod bloğunu aynı satıra yazabilirsiniz:

if a == 4 then a = 7 end
#ya da 
if a == 4: a = 7 end   # Ruby 1.9 ile bu kullanım kaldırılmıştır
# daha yüksek versiyonlarda hata verir


Bu şu şekilde de ifade edilir:

  a = 5
  a = 7 if a == 4
  print a    # if bloğu işletilmediği için 5 yazacaktır


unless ifadesi

düzenle

Unless işlemi if işleminin tersidir, eğer koşul sonucu yanlış ise kod bloğu işletilir.

Örnekler:

a = 5
unless a == 4
    a = 7
end
puts a     # unless bloğu işletildiği için 7 yazacaktır

unless işlemi hemen hemen tam anlamıyla if işleminin tersi olarak çalışır:

  if !işlem      # ''unless işlem'' ile aynı

Farkı, if işlemi 'W'elsif'W' ile karşılaştırmanın yanlış çıkmasıyla ikinci bir karşılaştırma yapabilir ama unless işleminin elsunless gibi bir devamı yoktur.

Ayrıca aynı if işlemindeki gibi :

a = 5
a = 7 unless a == 4
puts a    # unless bloğu işletildiği için 7 yazacaktır

Çalıştırılacak kod bloğu içinde tek satır olduğunda tek satırlık şekil daha yakışıklı olacaktır.


if-elsif-else işlemi

düzenle

elsif (dikkat edin elsif yazılır elseif değil) ve else blokları sayesinde birbiriyle alakalı birçok test yaparak programınızı daha etkili kontrol edebilirsiniz. elsif ve else blokları sadece if karşılaştırması yanlış ise işlenir. Birçok elsif bloğu olabilir ama sadece bir if ve bir else olabilir.

Yazım:

  if işlem
    ...kod bloğu...
  elsif başka işlem
    ...kod bloğu...
  elsif başka işlem
    ...kod bloğu...
  else
    ...kod bloğu...
  end


kısa-if işlemi (ternary operatör)

düzenle

"kısa-if" işlemi bir karşılaştırma sonucunda değerler dönmek için kestirme yoldur. String birleştirmelerinde koşullu işler yapmak için idealdir. Formatı şöyle :

sonuç = (koşul) ? (koşul-doğruysa-ifade) : (koşul-yanlışsa-ifade)

Buna ternary operatörü de denir ve böyle kısa şekliyle kısa işelrimizde kullanırız, mesela yazı şekilllendirmelerinde vs ama görsel bozukluğu unutulmamalıdır.

Örnek:

irb(main):037:0> true ? 't' : 'f'
=> "t"
irb(main):038:0> false ? 't' : 'f'
=> "f"
a = 5
plus_or_minus = '+'
print "#{a}#{plus_or_minus}1 işlemi sonucu: " + (plus_or_minus == '+' ? (a+1).to_s : (a-1).to_s) + "."

Ayrıca bu yapı yerine şu da kullanılabilir :

sonuç = if koşul then ifade_1 else ifade_2 end

Atamalar şu şekil yapılabilir :

sonuç = (değer_1 if ifade_1) || (değer_2 if ifade_2)


case işlemi

düzenle

Yukarıda açıklanan if-elsif-else işlemlerinin bir başka alternatifi olarak case işlemi kullanılır. Ruby'de case işlemi çoklu işlemi destekler. Örneğin bir sayı ile 5 arasındaki ilişkiyi tayin etmek istiyoruz :

a = 1
case 
    when a < 5 then puts "#{a}, 5 ten küçüktür"    
    when a == 5 then puts "#{a}, 5 e eşittir"   
    when a > 5 then puts "#{a}, 5 ten büyüktür" 
end

Not olarak eşitliği test ederken == kullanılır. Atama yapmak için = kullanılır. Şu durumda Ruby atama yapacaktır:

    when a = 5 then puts "#{a}, 5 e eşittir"   # DİKKAT! Bu kod 'a' değerini değiştirir!

Bu bizim istediğimiz değil! Biz burada karşılaştırma yapmak istiyoruz.

Daha kestirme bir yol olarak case ile karşılaştırma yapılacak değişkeni baştan verebiliriz:

case a
    when 0..4 then puts "#{a}, 5 ten küçüktür"    
    when 5 then puts "#{a}, 5 e eşittir" 
    when 5..10 then puts "#{a}, 5 ten büyüktür" 
    else puts "istenmeyen değer #{a} "         # a 10 dan büyük ya da negatif
end

Not: Range'ler açıkça açıkça belirtilmiş aralıklar olduğu için a'nın istenmeyen değerlerini sınırlamak için kullanılır. Bu kestirme yol olası değerler bilindiğinde çok faydalı olacaktır. Örneğin :

a = "elma"
puts case a
    when "vanilya" then "bir baharat"    
    when  "ıspanak" then "bir sebze" 
    when "elma"  then "bir meyve" 
    else "beklenmeyen değer"
end

Bu satırları irb'de girerseniz :

 bir meyve
 =>nil

Case hakkında diğer bilgileri Linuxtopia Ruby Programming [1] adresinde bulabilirsiniz.


Döngüler

düzenle

Ruby'de while ifadesi kullanım olarak if ve diğer dillerdeki while ifadesine benzer:

while < işlem >
  <...kod bloğu...>
end

Kod bloğu işlem sonucu true olduğu sürece tekrar tekrar işlenecektir.

Ayrıca aynı if ve unless ifadelerinde olduğu gibi, şöyle de mümkündür:

<...kod...> while < işlem >

Aşağıdaki ilginç kodu inceleyin...

 line = readline.chomp while line != "bunu arıyordum"

Bu satır çalıştırılınca konsoldan girilen satırları alır ve "bunu arıyordum" yazısı girilene kadar döngü bitmez.

until ifadesi işleyiş olarak while ifadesine benzer. while ifadesinin tersine until kullanılınca kod bloğu işlemin sonucu false olduğu sürece işlenir.

until < işlem >
  <...kod bloğu...>
end


for döngüsü

düzenle

for döngüsü bir for kelimesi ve arkasından argüman olarak iterasyonda kullanılacak bir yerel değişken adı, arkasından gelen in kelimesi ve her elemanı üzerinde iterasyon yapılacak değerden oluşur. do kelimesi opsiyoneldrir:

for value in [1, 2, 3] do
    puts value
end
# 1, 2 ve 3 yazar

Aynı while ve until gibi do kelimesi opsiyoneldir. for döngüleri yeni bir değişken kapsamı oluşturmaz.

for döngüsünün dönen değeri üzerinde iterasyon yapılan argümandır, Ama döngüden break ile çıkılırsa nil döner.

Modersn Ruby programlarında for döngüsü sık kullanılmaz.


break deyimi

düzenle

Bir kod bloğunu acilen terk etmek için break deyimi kullanılır. Aşağıdaki kod üzerinde iterasyon yapılan sayı çift ise bloğu terk eder, döngü biter:

values.each do |value|
    break if value.even?

    # ...
end

Bir while döngüsünü de break bitirebilirsiniz :

a = 0

while true do
  p a
  a += 1

  break if a < 10
end

p a

Bu arada p de puts ve print benzeri bir çıktı yazdırma komutu (aslında puts a.inspect eşleniğidir). Bu kod ekrana 0 yazar ve döngüden çıkar, çıkınca da o anki a değeri olan 1 yazar.

break çıktığı noktaya ait bir bilgi içeren ifadeyi argüman olarak alabilir :

result = [1, 2, 3].each do |value|
  break value * 2 if value.even?
end

p result # 4 yazar


redo deyimi

düzenle

redo ile içinde bulunulan döngü adımı tekrar edilir :

result = []

while result.length < 10 do
  result << result.length

  redo if result.last.even?

  result << result.length + 1
end

p result

Çıktı [0, 1, 3, 3, 5, 5, 7, 7, 9, 9, 11]


next deyimi

düzenle

next ile içinde bulunulan döngü adımının sonuna atlanır yani ondan sonraki kısmı pas geçilip , sonraki iterasyon adımına geçilir :

result = [1, 2, 3].map do |value|
  next if value.even?

  value * 2
end

p result # prints [2, nil, 6]

next dönen değeri de argüma olarak alabilir :

result = [1, 2, 3].map do |value|
  next value if value.even?

  value * 2
end

p result # prints [2, 2, 6]


retry deyimi

düzenle

Ruby 1.9 ve sonrasında bu deyim yerine redo kullanılmaya başladı.

Anahtar Kelime

düzenle

return değer satırı içinde bulunduğu metodun değer ile geri dönmesini sağlar.

Önceki: Söz Dizimi/Operatörler Index Sonraki: Söz Dizimi/Metod Çağrıları