Ruby/Sınıflar ve nesneler
←Metod tanımlamak | Sıaradışı Durumlar→
Ruby Sınıfları (Classes)
[düzenle]Önce de söylediğimiz gibi Ruby'de her şey bir nesnedir. Her nesnenin de üretildiği bir sınıf (class) vardır. Mesela "Ahmet" nesnesi "İnsan" sınıfından üretilmiştir gibi. Bir nesnenin sınıfının ne olduğunu öğrenmek için class metodu kullanılır. Örneğin şunu deneyin:
puts "Bu bir string".class
puts 9.class
puts ["bu", "bir", "array"].class
puts ({:bu => "da", :bir => "hash"}).class
puts :sembol.class
Her neyse bunları daha önce de gördünüz. Ancak bununla beraber nasıl kendi sınıfınızı tanımlayabileceğinizi veya Ruby sınıflarını nasıl devşirip geliştireceğinizi bilmiyorsunuz.
Bir Sınıfın Oluşumunu Üretmek
[düzenle]Bir sınıfın oluşumu bir nesne'dir (object) ve o sınıfa aittir. Örneğin "chocolate" nesnesi String
sınıfının bir oluşumudur. Bildiğiniz gibi string'ler, array'ler, hash'ler, number'lar, ve diğer bir kısım ön-tanımlı tipleri tırnaklar, köşeli parantezler, süslü parantezler vs. kullanarak üretebiliyorsunuz, ama bunları new metodunu kullanarak da üretebilirsiniz. Örneğin my_string = "" ve my_string = String.new satırları aynı işi yapar. Hemen tüm sınıflarda new metodu vardır: array'ler, hash'ler, her neyse. (Bazı sınıflar , mesela Integer ve Numeric new
metoduna sahip değildir. Bu sınıflar oluşum nesneleri içinde kopyalamaya izin vermez.) Kendi sınıfınızı tanımladığınızda da new metodu ile oluşum nesneleri üretirsiniz.
Sınıf Tanımlamak
[düzenle]Sınıflar bir nesnenin veri tipini temsil eder, mesela bir kitap, bir balina, bir üzüm veya çikolata. Herkes çikolata sever (doğru mu?), hadi o zaman bir çikolata sınıfı tanımlayalım:
class Çikolata
def ye
puts "Çok lezzetli!"
end
end
Koda bir bakalım. Sınıflar class ifadesi ile üretilir. Bundan sonra sınıfın adı gelir. Tüm sınıf isimleri büyük harfle başlamalıdır. Teamüllere göre sınıf isimlerinde CamelCase kullanıyoruz. Yani ParçaÇikolata isimli bir sınıfımız olabilir ama Parça_Çikolata şekli (SnakeCase) tercih edilmesi tavsiye edilmez.
Sonraki kısımda bir sınıf metodu kullanacağız. Sınıf metodu, bir sınıf için özel tanımlanmış bir metoddur. Örneğin String
sınıfının length metodu:
# 5 yazacaktır
puts "hello".length
Bizim Çikolata sınıfımızın ye metodunu , bu sınıftan oluşturulan bir nesnede kullanmak için şu kodu kullanabiliriz:
çikolata1 = Çikolata.new
çikolata1.ye # ekrana "Çok lezzetli!" yazar
Ayrıca bir metodu çağırmak için send de kullanabilirsiniz. Hani bir zaman "metodlar nesnelere gönderilen mesajlardır" demiştik:
puts "hello".send(:length) # 5 yazacaktır
çikolata1.send(:ye) # "Çok lezzetli!" yazar
Ancak send kullanımı, eğer dinamik bir davranış istemiyorsanız çok seyrektir, metod adını değer ifadesi olarak yazmamıza pek gerek olmaz. Ama olursa buraya bir değişken koyup değişik isimlerdeki metodları aynı satırla çağırabiliriz, ihtiyaca göre değişir, ama temiz bir kod görünümü değil.
Dikkat ettiyseniz Ruby'de tipik metod tanımlaması def deyimi ile başlar. Ancak metod adının da dinamik davranışta olması için define_method() yapısını send ile birleştirerek de kullanabilirsiniz:
class Foo
self.class_eval {
define_method(:'hey') { puts 'Hey dostum!' }
}
end
foo = Foo.new
foo.send :'hey' # => Hey dostum!
Self Kelimesi
[düzenle]Bir sınıfının metodu içinde self sahte değişkeni (pseudo değişken denir ve değiştirilemez) bulunulan oluşum nesnesini ifade eder. Örneğin:
class Integer
def more
return self + 1
end
end
puts 3.more # -> 4
puts 7.more # -> 8
Mevcut Integer sınıfına metod ilave ettik fark ettiyseniz.
Sınıf Metodları
[düzenle]Ayrıca , oluşturulan nesnede değil sınıfta çalışacak metodlar da tanımlanabilir. Örneğin:
class Çilek
def Çilek.renk
return "kırmızı"
end
def self.boyut
return "biraz küçük"
end
class << self
def şekil
return "çilek gibi"
end
end
end
puts Çilek.renk # -> "rekırmızıd"
puts Çilek.boyut # -> "biraz küçük"
puts Çilek.şekil # -> "çilek gibi"
Ama bu metodları oluşum nesnesinde çağırırsanız bulunamayacaktır:
çilek1 = Çilek.new
puts çilek1.renk
undefined method `renk' for #<Çilek:0x...> (NoMethodError)
Çünkü bunlar nesnenin değil sınıfın metodlarıdır.
3 değişik tanımlama tekniği kullanılmış: SınıfAdı.metod_adı ve self.metod_adı şekli aşağı yukarı aynı yapıda — metod tanımı bloğu dışında sınıf içindeki self sınıfın kendisini temsil eder. En sonuncu yapı ise birçok metod tanımlayacaksak her seferinde self kullanmamızı ve daha temiz bir görünümü sağladığı için tercih edilir. Buradaki class << self yapısı bizi sınıfın meta-sınıfı bağlamına götürür (bazen öz-sınıf da denir). Meta-sınıf aslında o sınıfın devşirildiği bir üst sınıfı ifade ediyor ama endişelenmeyin burada sadece self. kelimesini habire tekrarlamadan metod tanımı yapmanızı sağlıyor o kadar.