Merhabalar ben saldırı timlerinden Bunjo, bu konuda Meta Programlama'nın ne olduğunu anlatacağım.
Meta Programlama Nedir?
Meta programlama, bir bilgisayar programının kendi yapısını ya da başka bir programın yapısını manipüle etme yeteneğini ifade eder. Bu, bir programın çalışma zamanında kodu oluşturmasına, değiştirmesine ya da değerlendirmesine olanak tanır. Meta programlama, programlama dilinin kendisine ve dilin çalışma zamanındaki özelliklerine dayanır.
Meta programlama, genellikle bir programın esneklik, genişletilebilirlik ve dinamizm kazanmasına yardımcı olan bir araçtır. Bu teknik, özellikle dinamik olarak oluşturulan kod, sınıflar ve metodlar gibi konseptlerle ilişkilidir. Bir dilin meta programlama yetenekleri, o dilin sınıf modeli, refleksiyon (yansıma) özellikleri ve dinamik kod oluşturma yetenekleri gibi unsurlarına bağlı olarak şekillenir.
Ruby gibi dinamik tipli ve açık sınıf modeline sahip diller, meta programlama için oldukça uygundur. Bu dillerde, sınıflar ve nesneler çalışma zamanında dinamik olarak değiştirilebilir. Bu sayede, programcılar programlarını daha esnek ve modüler hale getirebilirler.
1. Reflection (Yansıma):
Ruby'de reflection, bir nesnenin ya da sınıfın özelliklerini ve metodlarını çalışma zamanında inceleme yeteneğini ifade eder.
Aşağıdaki örneklerde, reflection kullanarak bir nesnenin sınıfını, metodlarını ve özelliklerini nasıl sorgulayabileceğimizi görelim:
Ruby:
class Person
attr_accessor :isim, :dil
def initialize(isim, dil)
@isim = isim
@dil = dil
end
def selamla
"Bu bir örnek metod"
end
end
bunjo = Person.new("Bunjo", "Ruby")
puts("İsim: #{bunjo.isim}")
puts("Sınıf: #{bunjo.class}")
puts("Dil: #{bunjo.dil}")
puts("Değişkenler: #{bunjo.instance_variables}")
puts("Metodlar: #{bunjo.methods}")
puts("Kontrol (selamla): #{bunjo.respond_to?(:selamla)}")
Person sınıfı oluşturuluyor.
attr_accessor ile :isim ve :dil adlı özelliklere getter ve setter metodları ekleniyor.
initialize metodu, sınıf bir nesne oluşturulduğunda çağrılan bir yapıcı metod. Bu metod, isim ve dil adlı özelliklere başlangıç değerleri atıyor.
selamla metodu, sınıfa ait bir örnek metod. Bu metod, basit bir metin döndürüyor.
bunjo adlı bir Person nesnesi oluşturuluyor ve "Bunjo" ismi ile "Ruby" dilini içeriyor.
puts komutlarıyla oluşturulan nesnenin özellikleri ekrana yazdırılıyor. isim, class, dil, instance_variables, methods ve respond_to?
metodu kullanılarak özellikleri ve metodları kontrol ediliyor.
Çıktı:
Ruby:
İsim: Bunjo
Sınıf: Person
Dil: Ruby
Değişkenler: [:@isim, :@dil]
Metodlar: [:dil=, :selamla, :isim, :isim=, :dil, :hash, :singleton_class, :dup, :itself, :methods, :singleton_methods, :protected_methods, :private_methods, :public_methods, :instance_variables, :instance_variable_get, :instance_variable_set, :instance_variable_defined?, :remove_instance_variable, :instance_of?, :kind_of?, :is_a?, :display, :public_send, :class, :tap, :frozen?, :yield_self, :then, :extend, :clone, :<=>, :===, :!~, :method, :public_method, :nil?, :singleton_method, :eql?, :respond_to?, :define_singleton_method, :freeze, :inspect, :object_id, :send, :to_s, :to_enum, :enum_for, :!, :equal?, :__send__, :==, :!=, :__id__, :instance_eval, :instance_exec]
Kontrol (selamla): true
2. Open Classes (Açık Sınıflar):
Ruby, açık sınıf modeli sayesinde çalışma zamanında mevcut sınıfları genişletebilme veya değiştirebilme imkanı tanır.
Aşağıdaki örnekte, bir sınıfa dinamik olarak yeni bir metod ekleyerek açık sınıf modelini nasıl kullanabileceğimizi görelim:
Ruby:
class Dog
def bark
"Bunjo Ruby'i Seviyor!"
end
end
class Dog
def sit
"Bunjo Java'dan Nefret Ediyor!"
end
end
puts Dog.new.bark
puts Dog.new.sit
İlk olarak, Dog sınıfı tanımlanıyor ve bu sınıfın içinde bark adlı bir metot bulunuyor. bark metodu çağrıldığında, bir metin dizesi olan "Bunjo Ruby'i Seviyor!" geri döndürülüyor.
Ardından, aynı Dog sınıfı üzerine ikinci bir tanım ekleniyor. Bu sefer, sit adlı bir metot ekleniyor. sit metodu çağrıldığında, "Bunjo Java'dan Nefret Ediyor!" metni döndürülüyor.
Son olarak, Dog sınıfının iki metodu da kullanılarak nesne oluşturuluyor ve bu metodlar çağrılarak ekrana yazdırılıyor.
Çıktı:
CoffeeScript:
Bunjo Ruby'i Seviyor!
Bunjo Java'dan Nefret Ediyor!
3. Define Method (Metod Tanımlama):
Ruby'de define_method kullanarak çalışma zamanında dinamik olarak yeni metodlar tanımlayabiliriz.
Aşağıdaki örnekte, define_method ile bir sınıfa dinamik olarak metodlar ekleyerek nasıl kullanabileceğimizi görelim:
define_method Metodu:
Ruby'de, define_method özel bir metodu kullanarak dinamik metodlar tanımlanabilir.
Bu metod, sınıfın veya modülün içinde çalışma zamanında bir metodun adını ve davranışını belirlemenizi sağlar.
Ruby:
class MyClass
define_method :dynamic_method do
puts "Bu bir dinamik metod."
end
end
obj = MyClass.new
obj.dynamic_method
send ve define_method Kullanımı:
Ruby'de, send metodu ile çalışma zamanında bir nesnenin metodunu çağırabilirsiniz. Bu, programın çalışma zamanında karar verilen bir metodun çağrılmasına olanak tanır. Aynı zamanda, define_method ile dinamik olarak bir metodun tanımını yapabilir ve sonra send ile çağırabilirsiniz.
Ruby:
class MyClass
define_method :dynamic_method do
puts "Bu bir dinamik metod."
end
end
obj = MyClass.new
obj.send(:dynamic_method)
remove_method ve undef_method:
Ruby'de, bir sınıftan veya modülden bir metodun tanımını kaldırmak için remove_method veya undef_method kullanılabilir. remove_method mevcut bir metodun tanımını kaldırırken, undef_method mevcut bir metodun çağrılmasını tamamen engeller.
Ruby:
class MyClass
def existing_method
puts "var olan metod."
end
remove_method :existing_method
# veya
undef_method :existing_method
# artık çağırılamaz
end
Daha iyi anlamanız için:
Normal Metodlar (Static Methods):
Normal metodlar genellikle sınıf düzeyinde tanımlanır ve sınıfın örnekleri üzerinden çağrılır.
Bu metodlar, sınıfın örneklerine ait değil, sınıfın kendisine aittir. Yani, önce sınıf adı sonra nokta işareti (.) ve ardından metod adı kullanılarak çağrılır.
Normal metodlar, metodun alacağı parametreleri ve döndüreceği değeri belirten bir imza ile tanımlanır.
Dinamik Metodlar (Dynamic Methods):
Dinamik metodlar, sınıf veya nesne düzeyinde dinamik olarak oluşturulabilir ve çağrılabilir.
Bu metodlar çalışma zamanında oluşturulabilir, silinebilir veya değiştirilebilir. Ruby'de sınıflar ve nesneler açısından oldukça esnek bir yapıya sahiptir.
Dinamik metodlar genellikle define_method gibi özel metodlar kullanılarak tanımlanır.
4. Module Include (Modül Ekleme):
Ruby'de modüller, ortak davranışları gruplamak için kullanılır ve sınıflara eklenerek onlara yeni yetenekler kazandırabilirler.
Aşağıda, bir sınıfa dinamik olarak bir modül ekleyerek nasıl kullanabileceğimizi gösteren bir örnek bulunmaktadır:
Ruby:
module Greet
def selamla
puts("#{self.class}'dan Merhaba!")
end
end
class Person
end
Person.include(Greet)
Person.new.selamla
Oluşturulan Greet modülü selamla adında bir metod içerir. Bu metod, sınıfın adını ve "Merhaba!" mesajını ekrana yazdırır.
Oluşturulan Person sınıfı herhangi bir özel metod içermez. (İçi boş.)
Person sınıfının içine Greet modülü aktarılır ve artık Person sınıfı içinde Greet modülü çalıştırılabilir hale gelir.
Çıktı:
Person'dan Merhaba!
5. Method Missing (Metod Bulunamıyor):
Ruby'de method_missing metodu, bir nesnenin içinde bulunmayan bir metod çağrıldığında otomatik olarak çağrılan bir metodur.
Bu, dinamik olarak davranış eklemek ve belirli metod çağrılarını ele almak için kullanılabilir.
Ruby:
class BunjonunSınıfı
def method_missing(isim, *args)
puts "Metod bulunamadı: #{isim}"
end
end
obj = BunjonunSınıfı.new
obj.undefined_method # => Metod bulunamadı: undefined_method
Çıktı:
Metod bulunamadı: undefined_method
6. Alias Metod (Çağırılan Metodu Değiştirmek):
alias_method operatörü, Ruby'de bir metodun adını değiştirmek veya bir metodun eski adını saklamak için kullanılır.
Bu, özellikle sınıf hiyerarşisinde metodların isimlerini değiştirme ihtiyacı duyulduğunda veya bir metodun eski adına ihtiyaç duyulduğunda faydalıdır.
Ruby:
class MyClass
def original_method
puts "Metod Çağırıldı!"
end
# alias_method ile original_method'un adını değiştirme
alias_method :new_method, :original_method
end
obj = MyClass.new
obj.new_method
Yukarıdaki örnekte, MyClass sınıfında alias_method kullanılarak original_method'un adı new_method olarak değiştirilmiştir.
Bu durumda, new_method çağrıldığında aslında original_method çalışacaktır.
alias_method'un ilk parametresi, yeni metodun adını, ikinci parametresi ise eski metodun adını temsil eder.
alias_method ile yeni adı belirlerken, özel karakterlere (başka bir deyişle '_' veya 'ç') dikkat etmek önemlidir.
Genellikle metod adları küçük harfle başlar ve snake_case olarak adlandırılır.
Bu durumda, new_method çağrıldığında aslında original_method çalışacaktır.
alias_method'un ilk parametresi, yeni metodun adını, ikinci parametresi ise eski metodun adını temsil eder.
alias_method ile yeni adı belirlerken, özel karakterlere (başka bir deyişle '_' veya 'ç') dikkat etmek önemlidir.
Genellikle metod adları küçük harfle başlar ve snake_case olarak adlandırılır.
Ruby:
alias_method :yeni_metod, :eski_metod # Doğru
alias_method :yeniMetod, :eskiMetod # Yanlış
alias_method genellikle sınıf içinde veya sınıfın içinde bulunduğu modül içinde kullanılır. Eğer sınıf dışında kullanılmaya çalışılırsa NoMethodError hatası alınabilir.
7. Method Chaining (Metod Zinciri):
Ruby'de metod zinciri, bir nesnenin üzerinde sıralı bir şekilde bir dizi metod çağrımı yapılmasını ifade eder.
Bu sayede bir nesnenin üzerinde yapılan bir değişiklik, bir sonraki metod çağrısına etki eder.
Ruby:
class Matematikci
def initialize(deger)
@deger = deger
end
def topla(x)
@deger += x
self # self'i döndürerek metod zinciri oluşturuyoruz
end
def carp(y)
@deger *= y
self
end
def sonuc
@deger
end
end
# Metod zinciri oluşturarak kullanım
sonuc = Matematikci.new(5).topla(3).carp(2).sonuc
puts sonuc # Çıktı 16 olacaktır.
Emeğe karşılık konuyu beğenip mesaj yazabilirsiniz. Okuyan herkese teşekkür ederim.
İyi forumlar.
İyi forumlar.