Pazartesi, Aralık 26, 2005

Rubyden Parıltılar 2 - Bloklar

Rubynin (sanırım Groovy, Python, Smalltalk gibi diğer OO dinamik dillerde de mevcut) çarpıcı özelliklerinden biri de bloklar. Aşağıda fibanacci sayılarını hesaplayan ve bunları konsola yazan bir kod parçası var:


def fib_up_to(max)
i1, i2 = 1, 1 # parallel assignment (i1 = 1 and i2 = 1)
while i1 <= max
yield i1
i1, i2 = i2, i1+i2
end
end
fib_up_to(1000) {|f| print f, " " }


Yukarıda blokların kullanımına bir örnek var. {|f| print f, " " } bir blok. fib_up_to metoduna -bir tür parametre olarak- bu blok gönderiliyor. yield ile metodun içinden, blok çağrılıyor.

Yukarıdaki kodun güzelliği farklı iki sorumluluğun çok net ve kolay bir şekilde birbirinden ayrıştırılmış olması (seperation of concerns). Blok, kendisine gönderilen bir nesneyi konsola yazdırmakla ilgileniyor. Metot fibonacci algoritmasıyla ilgileniyor. Her ikisi de birbirinin davranışlarından tümüyle bağımsız (orthogonal). Ancak ikisi birlikte kolaylıkla işbirliği yapabiliyor.

Bu örnek için şunu diyebilirsiniz, konsola bir değer yazdırmak için, bunu blokta yürütmenin ne faydası var? Doğrudan while döngüsünün içine bu satırı yazsak, daha basit ve hızlı olurdu.

Sadece bu örnek için bu iddia doğru. Ancak düşünün ki, fibonacci algoritmasını yeri geldikçe farklı ortamlarda kullanmanız gerekebilir. Bir yerde fibanacci dizisini veritabanına yazdırabilirsiniz, bir yerde bunu bir GUI'ye koyarsınız. Veya bu dizinin elemanlarıyla yeni matematiksel işlemler yapmanız gerekebilir. Bu gibi farklı ihtiyaçlar için, yukarıdaki metodu hiç değiştirmeniz gerekmez. Sadece metodun birlikte çalışacağı bloku yazmanız yeterli. Böylece fibanacci dizisini oluşturma mantığını sadece tek bir yerde yürütürsünüz (Don't Repeat Yourself - DRY).

Hiç yorum yok: