4 Metotlar Hemen her programlama dilinde var olan metot kavramı Ruby için de aynıdır. Bazı kaynaklarda metot terimi yerine fonksiyon terimi kullanılır. Bu kitapta iki terimi eşanlamlı kullanacağız. Ruby metotarının genel sözdizimi şöyledir ([17], [15]): Liste 4.1. d e f metot_adı [ ( [ arg [= d e f a u l t ] ]... [, arg [, &expr ] ] ) ] deyim ( l e r ) Metot bildirimi def anahtar sözcüğü ile başlar, aynı satıra metot adı sonra varsa metodun parametreleri (arguments) yazılır. Sonra satırbaşı yapılarak metot gövdesi başlatılır. Metot gövdesine metoda yaptırılacak işleri yapan deyimler alt alta yazılır. Gövdeye yazılacak deyimler için bir kısıt yoktur. Hiç bir iş yapmayacak metotların gövdesi boş olabilir. Çok iş yapacak fonksiyonların gövdesine gerektiği kadar deyim yazılabilir. Deyimleri birbirlerinden ayırmak için ya her deyim ayrı bir satıra yazılır ya da deyimler arasına (;) konulur. En son satıra anahtar sözcüğü konulur., metot bildiriminin bitiş yeridir. Ruby metotları değer veren (return) ya da değer vermeyen metotlar diye ikiye ayrılabilir. değer vermeyenler, bazı dillerdeki procedure diye adlandırılan yapının rolünü oynar. Metot tek ya da çoklu değer verebilir (return values). Genel kural olarak, bir metoda bir tek iş yaptırmalıyız. Böylece metodun taşınabilirliği sağlandığı gibi, güncellenmesi de kolay olur. Tabii, bir metoda birden çok iş yaptıracak deyimlerin yazılması mümkündür, ama bu iyi bir yöntem değildir.
44 BÖLÜM 4. METOTLAR Metodun vereceği değeri, gövdenin son satırında return anahtar terimi ile belirtmek mümkündür. Ama Ruby buna gerek duymaz; gövdedeki son satır değerini return değeri olarak verir. Bilgisayar dillerinde, metot adını izleyen () içine yazılan değişkenlere parametreler (parameters) ya da argümanlar (arguments) denilir. Fonksiyon gövdesi içine öntakısız yazılan değişkenlere de yerel değişken adı verilir. Argümanlara fonsiyon çağrılırken gerçek değerler atanır. Yerel değişkenler, içinde oldukları ifadeye göre değer alırlar. Yerel değişkenlerin kapsanma alanı (scope) yalnızca içinde bulundukları metodun gövdesidir. Fonksiyonun yerel değişkenlerine dışarıdan erişilemez. 4.1 Metot Sözdizimleri Ruby metot bildiriminde farklı sözdizimleri (syntax) kullanılabilir. 4.1.1 Parametresiz Metot Bildirimi En basit fonksiyon bildirimi, parametresi olmayan fonksiyon bildirimleridir: Liste 4.2. d e f metot_adı 2 deyim ( l e r ) Parametresiz metot çağrılırken yalnızca adı yazılır: metot_adı 4.1.2 Parametreli Fonksiyon Bildirimi Parametreler yalın olabileceği gibi array gibi yapısal tipler de olabilir. Liste 4.3 deki metot x ile y argümanlarına bağlıdır. x ile y değişkenleri her veri tipinden olabilir. Liste 4.3. d e f metot_adı ( x, y ) 2 deyim ( l e r )
4.1. METOT SÖZDIZIMLERI 45 Parantezler kullanılmayabilir Metodun parametreleri () içine konulmayabilir Liste 4.3 deki metodu Liste 4.4 gibi de yazabiliriz. Parametreler rasına virgül (,) konulur. Liste 4.4. d e f metot_adı x, y 2 deyim ( l e r ) Parametreli metot çağrılırken, parametrelere gerçek değerler atanır. Metot bildirimindeki değişkenlere parametre demiştik. Metot çağrısında parametrelere atanan değerlere gerçek parametre değeri denilir. Gerçek parametre değerleri, bir literal (sabit) olabileceği gibi, değeri programda bulunabilen bir ifade ya da fonksiyon olabilir. 4.1.3 Parametrelere Öntanımlı Değer Atama Metot parametrelerine bildirimde öntanımlı (default) değerler atanabilir. Metot çağrılırken parametresiz çağrı yapılırsa, öntanımlı değerler işlevsel olur. Ama, istenirse, çağrıda başka parametre değerleri kullanılabilir. Liste 4.5. d e f metot_adı ( x = değer1, y = değer2 ) 2 deyim ( l e r ) Program 4.1 deki bildirimde argümanlara öntanımlı değerler atanmıştır. Metot çağrılırken parametre kullanılmazsa; yani parametresiz çağrı yapılırsa, öntanımlı değerler işler. Ama çağrıda öntanımlı değelerden farklı parametre değerleri kullanılırsa, öntanımlı değerler işlevsiz kalır, yeni değerler işler. Program 4.1. 2 7 #! / usr / bin /ruby d e f d i l l e r ( x="ruby", y=" Python " ) puts " #{x} programlama d i l i n i öğreniyorum. " puts " #{y} programlama d i l i n i öğreniyorum. " d i l l e r d i l l e r " Java ", "C++"
46 BÖLÜM 4. METOTLAR / Ruby programlama d i l i n i öğreniyorum. Python programlama d i l i n i öğreniyorum. Java programlama d i l i n i öğreniyorum. 5 C++ programlama d i l i n i öğreniyorum. 4.1.4 Return Değeri Her Ruby metodu, öntanımlı olarak son satırındaki değeri return değeri olarak verir. Örneğin Liste 4.6. d e f t e s t i = 10 j = 20 4 k = 30 p r i n t t e s t metodunun öntanımlı değeri son satırındaki 30 değeridir. Ruby metodunun birden çok return değeri vermesi isteniyorsa, son satıra Liste 4.7. r e t u r n [ deyim [, deyim ( l e r )... ] ] yazılır. Liste 4.8. d e f t e s t i = 100 j = 200 4 k = 300 r e t u r n i, j, k var = t e s t puts var / 2 100 200 300
4.1. METOT SÖZDIZIMLERI 47 4.1.5 Değişken Sayıda Parametre Genel olarak, fonksiyon çağrılırken parametrelerin hepsine gerçek değerler verilir. Değerlerin yazılış sırası, parametrelerin yazılış sırasıdır. Ancak, Ruby, değişken sayıda parametre kullanılmasına izin verir. Bunun için, metot bildiriminde parametrenin önüne joker (*) konulur: Program 4.2. d e f t e s t d e f sample ( t e s t ) puts " Parametre s a y ı s ı : #{t e s t. length } " f o r i i n 0... t e s t. length 5 puts " Parametreler : #{t e s t [ i ] } " sample " Manisa ", " 7 ", "G" sample "IBM", " 64 ", "V", "MIT" 1 / Parametre s a y ı s ı : 3 Parametreler : Manisa Parametreler : 7 Parametreler : G 6 Parametre s a y ı s ı : 4 Parametreler : IBM Parametreler : 64 Parametreler : V Parametreler : MIT 11 Program 4.3. # Array olarak v e r i l e n s a y ı l a r ı n o r t a l a m a s ı n ı bulur d e f ortalama_bul ( array ) 4 sum = 0.0 sonuç = 0.0 i f array. length > 0 then array. each do s a y ı sum += s a y ı 9 sonuç = sum / array. length r e t u r n sonuç 14 v e r i = [ 5. 5, 8. 7, 2. 6, 3. 9 ] ortalama = ortalama_bul ( v e r i ) puts " Ortalama #{ortalama } " / Ortalama 5. 175 3
48 BÖLÜM 4. METOTLAR 4.1.6 Çoklu Çıktıyı Array Olarak Elde Etme Program 4.4. d e f f i y a t _ a r t ı r ( info, percentage ) 2 sonuç = [ ] # Boş array yarat i n f o. each_index do i sonuç [ i ] = i n f o [ i ] (1 + ( percentage /100.0) ) r e t u r n sonuç 7 p r i c e = [ 6 7. 0 0, 43.00, 7 8. 0 0 ] new_price = [ ] 12 new_price = f i y a t _ a r t ı r ( price, 1 0. 0 ) puts new_price. j o i n ( ", " ) / 2 7 3. 7, 47. 300000000000004, 85. 80000000000001 4.2 Sınıf Metotları Sınıf metotları (class methods) doğrudan sınıftan çağrılabilen metotlardır. Java daki static metotlar gibidir. Metot adının önüne ait olduğu sınıf_ adı ya da self anahtar sözcüğü yazılarak tanımlanabilirler. Araya (.) bağlacı konulur. Program 4.5 ile Program 4.6 aynı işi yaparak deneme adlı sınıf metodunu tanımlarlar. Program 4.5. 2 d e f Test. deneme "Adım deneme. Ben b i r s ı n ı f metoduyum. " Program 4.6. d e f s e l f. deneme "Adım deneme. Ben b i r s ı n ı f metoduyum. " 5 Program 4.7 de sınıf metodu doğrudan Test sınıfından çağrılınca çalışıyor, ama anlık metot çalışmıyor (11. ve 12.satır). Tersine olarak, nesne içinden çağrılan metot2 çalışıyor ama metot1 çalışmıyor.
4.2. SINIF METOTLARI 49 Program 4.7. d e f s e l f. metot1 puts c l a s s metodu 5 d e f metot2 puts a n l ı k metot 10 Test. metot1 # => " s ı n ı f metodu " Test. metot2 # => NoMethodError : undefined method... Test. new. metot1 # => a n l ı k metot 15 Test. new. metot2 # => NoMethodError : undefined method... Ruby çok uysal bir dildir. Örneğin, Program 4.8 sınıf metodunu üç ayrı sözdizimi ile veriyor. Her üçü de çalışıyor. Programcı, kisine uygun olanı kullanabilir. Program 4.8. # Yl 1 d e f s e l f. smetot puts s ı n ı f metodu 5 Test. smetot # " c l a s s method " 10 #Yol 2 c l a s s << s e l f d e f smetot puts s ı n ı f metodu 15 Test. smetot # " s ı n ı f metodu " 20 # Yol 3 : ; d e f Test. smetot puts s ı n ı f metodu 25 Test. smetot # " s ı n ı f metodu " / s ı n ı f metodu 3 s ı n ı f metodu s ı n ı f metodu
50 BÖLÜM 4. METOTLAR 4.3 Anlık Metotlar Anlık (instance) metotlar anlık değişkenler gibi, ancak sınıftan üretilen nesne içinde işlevseldir. Program 4.9 de ses_ver metotlarından ilki self öntakısını aldığı için sınıf metodudur. Onu doğrudan Hayvan sınıfından çağırabiliriz. Ama ikinci ses_ver metodu anlık (instance) olduğu için, onu ancak Hayvan sınıfından türetilen kedi nesnesi içinden çağırabiliriz. Adları aynı olmakla birlikte, bu iki metodun aduzayları farlıdır. O nedenle çakışmazlar. Program 4.9. c l a s s Hayvan d e f s e l f. ses_ver #Class metodu puts "Möö! möööö! " 5 10 d e f ses_ver # a n l ı k ( i n s t a n c e ) metodu puts " miyaaav! miiiyaav " 15 kedi = Hayvan. new ( ) kedi. ses_ver # a n l ı k ( i n s t a n c e ) metot ç a ğ r ı l ı y o r Hayvan : : ses_ver # c l a s s metodu ç a ğ r ı l ı y o r / miyaaav! miiiyav Möö! möööö! 4 Program 4.10. 1 c l a s s String # metnin t e r s okunuşu a s l ı n a e ş i t s e palindrome dur. d e f palindrome? s e l f == s e l f. r e v e r s e 6 " l e v e l ". palindrome? / 2 true