diziler
Önceki
İçindekiler
İçindekiler
Kontrol Yapıları
Sonraki

 Ruby Kullanıcı KılavuzuBasit Örneklere Dönüş 

Şimdi eski örneklere tekrar göz atalım.

Aşağıdakini daha önce örnekler kısmında görmüştük.

def fact(n)
  if n == 0
    1
  else
    n * fact(n-1)
  end
end
print fact(ARGV[0].to_i), "\n"

Bu bizim ilk örneğimiz olduğu için her satırı teker teker açıklayalım.

Faktöriyeller

def fact(n)

İlk satırda bir fonksiyon (ya da daha özel olarak bir metot; metodun ne olduğunu ilerki kısımlarda göreceğiz) tanımlamak için def deyimini kullanıyoruz. Burada fonksiyonumuz fact'ın n adında tek bir argüman aldığını görüyoruz.

if n == 0

if bir kontrol deyimidir. Eğer koşul sağlanıyorsa onu takip eden kod değerlendirilir, aksi taktide else kısmına geçilir.

1

Eğer koşul sağlandıysa if'in değeri 1 olacaktır.

else

Eğer koşul tutulmadıysa, buradan end'e kadar olan kısım değerlendirilecektir.

n * fact(n-1)

Eğer koşul sağlanmamışsa sonuç n kere fact(n-1) olacaktır.

end

İlk end, if deyimini kapatmak için kullanılır.

end

İkinci end,def ifadesini kapatır.

print fact(ARGV[0].to_i), "\n"

Bu bizim komut satırından fact() fonksiyonunu çalıştırmamızı ve sonuçları ekranda görmemizi sağlar.

ARGV komut satırı argümanlarını içeren özel bir dizidir. ARGV dizisinin tüm elemanları dizgiler olduğu için, to_i metoduyla tamsayıya dönüştürmek zorundayız. Ruby Perl'deki gibi dizgileri tamsayılara otomatik olarak dönüştürmez.

Hmmm... Eğer bu programa negatif bir sayı girersek ne olur? Problemi görebildiniz mi? Peki düzeltebilir misiniz?

Strings

Şimdi önceki bölümdeki bulmaca örneğimizi tekrar inceleyelim. Bu sefer biraz daha uzun, kolaylık açısından satırları numaralandırdık.

01 kelimeler = ['kestane', 'gurgen', 'palamut']
02 gizli_kelime = kelimeler[rand(3)]
03
04 print "tahmin? "
05 while tahmin = STDIN.gets
06   tahmin.chop!
07   if tahmin == gizli_kelime
08     print "kazandin\n"
09     break
10   else
11     print "kaybettin.\n"
12   end
13   print "tahmin? "
14 end
15 print "kelime: ", gizli_kelime, ".\n"

Bu programda yeni bir kontrol yapısı gördük: while. Verilen koşul doğru olduğu sürece while ve end arasındaki kod tekrar tekrar çalıştırılacaktır.

2. satırdaki rand(3) fonksiyonu 0 ile 2 arasında rastgele sayı üretir. Bu rastgele sayı kelimeler dizisinin elemanlarından birini çıkarmak için kullanılır.

5. satırda STDIN.gets metoduyla standart girdiden bir satır okuduk. Eğer satırı alırken EOF (end of file) meydana gelirse gets, nil değerini döndürecektir. while ile ilişkilendirilmiş kod ^D (ya da DOS altında ^Z) görene kadar tekrarlanacaktır.

6. satırdaki tahmin.chop!, tahmin değişkeninin sonundaki yeni satır (newline) karakterini temizlemeye yarar.

15. satırda gizli kelimeyi yazdırıyoruz. Bunu üç argümanla birlikte bir yazdırma deyimi olarak kullandık (birbiri ardına yazdırılarak) ancak bunu daha efektif hale getirmek gizli_kelime yerine #(gizli_kelime) meotdu tanımlayarak bir tek arg�man alan birşey yazabilirdik:

print "kelime: #{gizli_kelime}.\n" 

Düzenli ifadeler

Sonunda programımızı düzenli ifadelerle inceleme sırası geldi.

01 st = "\033[7m"
02 en = "\033[m"
03
04 while TRUE
05   print "str> "
06   STDOUT.flush
07   str = gets
08   break if not str
09   str.chop!
10   print "pat> "
11   STDOUT.flush
12   re = gets
13   break if not re
14   re.chop!
15   str.gsub! re, "#{st}\\&#{en}"
16   print str, "\n"
17 end
18 print "\n"

4. satırda while'ın koşulu sonsuz döngüyü sağlamak için true yapılmıştır. Ancak döngüden çıkabilmek için 8. ve 13. satırlarda break kullandık. Bu iki break aynı zamanda if deyiminin niteleyicilerinden biridir. Bir if niteleyicisi sadece ve sadece koşul sağlandığı zaman sol elindeki deyimi çalıştırır.

chop! için (9. ve 14 satıra bakın) hakkında söylenecek çok şey var. Ruby'de geleneksel olarak metot isimlerinin sonuna '!' ya da '?' ekleriz. Ünlem işareti (! gurgenen "bang!" diye söylenir) potansiyel olarak yıkıcı bir görev görür, daha da açmak gerekirse; dokunduğu değeri değiştiren bir şeydir. chop! bir dizgiye direkt etki eder ancak ünlem işareti olmayan bir chop, bir kopya üzerinde çalışır. Aşağıda ikisi arasındaki fark görülüyor:

ruby> s1 = "forth"
  "forth"
ruby> s1.chop!       # Bu s1'i degistirir.
  "fort"
ruby> s2 = s1.chop   # s2'nin değiştirilmiş bir kopyasını koyar. 
  "for"
ruby> s1             # ... s1'e dokunmaz. 


  "fort"

İlerde sonunda soru işareti olan metot isimleriyle karşılaşacaksınız ( ? genelde "huh?" şeklinde telaffuz edilir). Bu true ya da false döndüren bir 'doğrulama' metodudur.

15. satırda dikkat edilmesi gereken önemli bir uyarı yer almaktadır. Öncelikle gsub!'ın başka bir sözde 'yıkıcı' metot olduğuna dikkat edelim. re'ye uyan her ne varsa str'nin yerine koyar (sub değiştirmek, g ise globalden gelir); verilen sadece ilk bulduğunu değil, dizgideki tüm eşleştirilen kısımları değiştirir. çok iyi, çok güzel; fakat eşleştirilen kısımları neyle değiştireceğiz? 1. ve 2 satırda st ve en adlı iki dizgi tanımladık. 15. satırdaysa bunları, olduğu gibi yorumlandıklarından emin olmak için #{} arasına yazdık (names değişkeninin yazdırıldığını görmeyiz). Hemen arkasından "\\&" kodunu görüyoruz. Bu küçük bir hiledir. Yer değiştirilen dizgi çift tırnak arasında olduğu için bir çift ters bölü işareti tek bir taneymiş gibi yorumlanır. Böylece gsub!'ın göreceği şey "\&" olur ve bu da ilk konumda ne eşleştirildiyse onu referans eden özel bir koda dönüştürülür.


diziler
Önceki
İçindekiler
İçindekiler
Kontrol Yapıları
Sonraki