Skip to content

Methods (Fonksiyonlar)

Programlama parçacıklarının ve/veya ifadelerin bir araya toplandığı şeydir method. Aslında lise matematiğinden hepimiz aşinayız.

Bildiğiniz matematik fonksiyonu. Bundan böyle fonksiyon yerine method kullanacağım. Çünkü Ruby demek neredeyse Obje (Nesne) ve Method (Method) demek.

Önceki konularda gördüğümüz operatörlerin neredeyse hepsi bir method! Hemen Method Definition'a yani nasıl method tanımlandığına bir göz atalım.

def merhaba
  "Merhaba"
end

merhaba        # => "Merhaba"

def ve end anahtar kelimeleri arasına method’un adı geldi. Önce method’u tanımladık, sonra çağırdık.

Ruby'de her şey mutlaka geriye bir şey döner. Ne demek bu? Prensip olarak method’lar zincir olarak çalıştığı için, method denen şey de aslında bir fonksiyon ve fonksiyon denen şey de bir dizi işlemin yapılıp geriye sonucun dönüldüğü bir taşıyıcı aslında.

Bir örnek vermek için hemen irb ye geçelim:

irb(main):001:0> puts "Merhaba"
Merhaba
=> nil
irb(main):002:0>

puts "Merhaba" önce işini yaptı ve çıktı olarak Merhaba verdi. sonra => nil dikkatinizi çekti mi?

Çünkü puts method’u işini yaptı bitirdi ve geriye nil döndü! Peki daha önceki programlama tecrübelerimize dayanak, geriye döndü işini hangi komut yapmış olabilir?

Pek çok dilde fonksiyondan bir şey geri dönmek için return kelimesi kullanılır. Ruby'de de kullanılır ama zorunlu değildir. Yukarıdaki def merhaba örneğinde return kullanmamamıza rağmen geriye Merhaba dönebildi.

Ruby'de methodlar içerisindeki çalıştırılan en son satırın değerini döndürür. Ancak siz daha öncesinde özellikle return anahtar kelimesi ile bir sonuç dönmezseniz. Bir örnekle konuyu pekiştirelim.

def merhabaBir
  m = "Merhaba"
  n = "Ornek"
end

def merhabaIki
  m = "Merhaba"
  n = "Ornek"
  return "Return Ornek"
end

puts merhabaBir   # Sonuç : Ornek
puts merhabaIki   # Sonuç : Return Ornek

İşte bu Ruby'nin özelliği. Kodu okurken bunu bilmezsek kafamız süper karışabilir.

def ile tanımlanan method’u, undef ile yok edebilirsiniz.

def merhaba
  "Merhaba"
end

merhaba # => "Merhaba"

undef merhaba

merhaba # =>
# ~> -:9:in `<main>': undefined local variable or method `merhaba' for main:Object (NameError)

Gördüğünüz gibi undefined local variable or method .. Object (NameError) hatasını aldık.

Method’lar argüman alabilir. Yani fonksiyona, doğal olarak, parametre geçebilirsiniz.

def merhaba(isim)
  "Merhaba #{isim}"
end

merhaba("vigo") # => "Merhaba vigo"

aynı örneği aşağıdaki gibi de yazabiliriz:

def merhaba isim
  "Merhaba #{isim}"
end

merhaba "vigo" # => "Merhaba vigo"

Method’u tanımlarken ve çağırırken parantez kullanmadık! Bu alışmanız gereken önemli konulardan birisi. Şahsen ben, daha önce hiçbir programlama dilinde böyle bir şey görmedim!

Bazı durumlara, argüman alan method çağırırken, argümanın tipine göre, eğer parantez kullanmadan çağırma yaparsanız warning alabilirsiniz!

Method Yazma Kuralları (Method Conventions)

Ruby, pek çok konuda rahat gibi görünse bile bazı kuralları var tabi. Özellikle method’ların son karakteri ile ilgili. Eğer bir method’un son karakteri ? ise bu o method’un true ya da false yani Boolean bir değer döneceğini ifade eder.

a = "ali"
b = "ali"

a.eql? b  # => true
a.eql?(b) # => true

.eql? method’u eşitliği kontrol eder ve mutlaka sonuç Boolean döner.

Eğer method’un son karakteri ! (Ünlem) ise; bu, o method’un tehlikeli bir iş yaptığını anlatır. Yani ilgili nesnenin kopyalanmadan direk üzerinde değişiklik yapacağı anlamına gelir.

a = "deneme"

a.upcase   # => "DENEME"
a          # => "deneme"

a.upcase!  # => "DENEME"
a          # => "DENEME"

a değeri deneme. .upcase ile orijinal değeri değiştirmeden uppercase (Büyük harf) yaptık. Değeri kontrol ettiğimizde halen küçük harf olduğunu gördük. .upcase! kullandığımız anda değişkenin orijinal değerini de bozduk.

Eğer bir method = ile bitiyorsa, bu, o method’un bir setter method’u olduğu anlamına gelir ve Class ile ilgili bir konudur.

class User
  def email=(email)
    @email = email
  end
end

u = User.new
u # => #<User:0x007ff7229ed880>

u.email = "vigo@xyz.com"
u # => #<User:0x007ff7229ed880 @email="vigo@xyz.com">

Varsayılan Argümanlar (Default Arguments)

Method argümanlarına varsayılan değerler atayabilirsiniz. Bu, eğer methoda gönderilmesi beklenen argüman gelmemişse otomatik olarak değer atama yapmayı sağlar.

def merhaba(isim="insalık!")
  "Merhaba #{isim}"
end

merhaba          # => "Merhaba insalık!"
merhaba("vigo")  # => "Merhaba vigo"

Parametre geçmeden çağırdığımızda, tanımladığımız varsayılan (default) değer atandı.

Değişken Sayıda Argümanlar (Variable-Length Arguments)

Bazı durumlarda method’a değişken sayıda olarak parametre geçmek gerekebilir. Bu durumda argümanın başına * işareti gelir. Bu sayede o argüman artık bir dizi (Array) haline gelir.

def merhaba(*isimler)
  "Merhaba #{isimler.join(" ve ")}"
end

merhaba("vigo")                        # => "Merhaba vigo"
merhaba("vigo", "yeşim", "ezel")       # => "Merhaba vigo ve yeşim ve ezel"

merhaba "dünya", "uzay", "evren", "ay" # => "Merhaba dünya ve uzay ve evren ve ay"

Keza, şu şekilde de kullanılabilir:

def custom_numbers(first, second, *others)
  puts "ilk sayı: #{first}"
  puts "ikinci sayı : #{second}"
  puts "diğer sayılar : #{others.join(",")}"
end

custom_numbers 1,2,50,100 # => nil
# >> ilk sayı: 1
# >> ikinci sayı : 2
# >> diğer sayılar : 50,100

Method’a Takma İsim Vermek (Aliasing)

Varolan bir method’u, başka bir isimle çağırmak. Bu aslında Class konusuyla çok ilintili ama kısaca değinmek istiyorum.

def merhaba(isim)
  "Merhaba! #{isim}"
end

alias naber merhaba

merhaba "Uğur" # => "Merhaba! Uğur"
naber "Uğur"   # => "Merhaba! Uğur"

Formül şu: alias TAKMA AD ORİJİNAL yani alias naber merhaba derken, merhaba method’una takma ad olarak naberi tanımladık!

Unutma!

  • return kullanmadan method’dan geri dönüş yapılabilir
  • Parantez kullanmadan method tanımlanabilir
  • Parantez kullanmadan method çağırılıp parametre geçilebilir.
  • ? ile biten method mutlaka true ya da false döner.
  • ! ile biten orijinal değeri mutlaka değiştirir.
  • = ile biten setter'dır.