Monkey Patching
Ruby’nin en şaibeli özelliklerinden biridir. Kimileri için müthiş bir şey kimileri için de çok tehlikeli bir özelliktir. 7.7’de bahsettiğim Meta Programming konusu ile de çok yakından alakalıdır.
Ruby’deki tüm sınıflar açıktır. Yani Kernel’dan gelen herhangi bir sınıfı modifiye etmek mümkündür. Bu durum yanlış ellerde çok tehlikeli olabilir.
Yani, String
sınıfındaki herhangi bir method’u bozmak mümkündür. Örneğin,
String#length
methodunu değiştirelim:
"Hello".length # => 5 # Bu normali
# Monkey Patching yapıyoruz ve length method’unu değiştiriyoruz.
class String
def length
"Uzunluk: #{self.size} karakterdir."
end
end
"Hello".length # => "Uzunluk: 5 karakterdir."
Normal şartlar altında length
methodu Fixnum
dönmesi gerekirken,
bozduğumuz method bize String
döndü. Anlatabilmek için bu denli abartı bir
örnek vermek istedim. Düşünsenize, kullandığınız herhangi bir kütüphane,
kafasına göre, standart olan herhangi bir method’u bu şekilde bozsa?
Tüm kodunuz çorbaya döner ve içinden çıkamaz bir hale gelir. Peki asıl kullanım amacı bu mudur? Tabiiki değil. Bize kolaylık sağlayan işlerde kullanmamız gerekiyor.
Örneğin, basit bir matematik işlemi için, 5 kere 5 önermesini kullanmak istiyoruz:
class Fixnum
def kere(n)
self * n
end
end
Fixnum
içine kere
diye bir method taktık. Haydi kullanalım:
5.kere(5) # => 25
5.kere(5).kere(2) # => 50
İşte bu tür bir Monkey Patching işe yarar ve kullanılabilitesi yüksek olan bir yöntemdir. Keza Ruby on Rails webframework’ü neredeyse bu mantık üzerine kurulmuştur.
Örneğin 5 gün önce şeklinde bir önerme yapmak istiyoruz.
class Fixnum
def gün
self * 24 * 60 * 60
end
def önce
Time.now - self
end
def sonra
Time.now + self
end
end
Şimdi şöyle bir şey yapalım:
Time.now # => 2015-02-09 12:55:33 +0200
5.gün.önce # => 2015-02-04 12:55:33 +0200
1.gün.sonra # => 2015-02-10 12:55:33 +0200
Fixnum
yani basit sayılara .gün.önce
ve .gün.sonra
gibi iki tane method ekledik :)