Ruby ile Reflection

Merhabalar,

Bu yazımızda Ruby üzerinde, daha Önce yazmış olduğum Ruby ile Çalışma Zamanı ve nesneler aynı mı ? yazılarında az da olsa değindiğim fakat genel anlamı ile hiç ele almadığım Ruby ile Reflection konusunda yazmaya karar verdim.

Reflection tanım olarak, çalışma zamanında programda tanımlanmış nesnelere veya methodlara dinamik erişimi tarif eder.
Aşağı yukarı günümüzde tüm modern (hatta bazı klasik) programlama dilleri bu olguyu destekler. Ruby, çalışma ve tasarım zamanlarının birbirlerinden farklı olmaması nedeni ile Reflection olgusunu tüm yÖnleri ile destekler.

Günümüzde Reflection Özelliği üzerine kurulu Reflective Programming adlı yeni bir yazılım geliştirme felsefesi de bulunmaktadır.

En temel anlamda düşünürsek, bir yazılımcı olarak yazdığınız program üzerinde %100 kontrol sahibi olmak isteriz. Tasarım zamanında (yani programı yazarken) elimizde olan bu gücü, çalışma zamanında da kendi yazdığımız diğer yazılımlar sayesinde (veya aracılığı ile) korumak isteyebiliriz. Reflection, tam bu esnada kullanmamız gereken teknolojinin adıdır.

Hemen, diğer yazılarımızda olduğu gibi Örneğimizi verelim;
Bu Örnekte SimpleClass adı altında küçük ama Ruby’nin pek çok Özelliğini kullanan bir sınıf oluşturup, bu sınıfın methodlarını, bu sınıftan veya diğer temel Ruby sınıflarından oluşturulmuş nesnelere dinamik olarak erişen bir uygulamaya yapmaya çalıştım.
[ruby]
class SimpleClass
@@object_count = 0 # Static bir değişken
# Reader’lar hazırlanıyor.
attr_reader :sequence, :name, :birth_year, :age
# Writer’lar hazırlanıyor.
attr_writer :name, :birth_year

def initialize(name, birth_year)
@name = name
@birth_year = birth_year
@age = Time.now().year – @birth_year
calc_sequence
end

def calc_sequence
@@object_count += 1
@sequence = @@object_count
end
# Object sınıfında bulunan to_s method’u eziliyor.
def to_s
“#{@sequence}. #{@name}, #{@birth_year}(#{@age})”
end

# Static method.
def self.object_count
@@object_count
end

# calc_sequence method’u private yapılıyor.
private :calc_sequence
end

# myClass1 ile SimpleClass tipinde nesne yaratılıyor ve method’ları inceleniyor.
myClass1 = SimpleClass.new(“Uordek”, 1979)
puts “Private methods : ” + (myClass1.class.private_instance_methods – myClass1.class.superclass.private_instance_methods).join(“,”)
puts “Public methods : ” + (myClass1.class.public_instance_methods – myClass1.class.superclass.public_instance_methods).join(“,”)
puts “Singleton methods : ” + (myClass1.class.singleton_methods – myClass1.class.superclass.singleton_methods).join(“,”)
puts “Parent classes : ” + myClass1.class.ancestors.join(“, “)

myClass2 = SimpleClass.new(“Sihaya”, 1981)
myClass3 = SimpleClass.new(“Ali”, 1985)
myClass4 = SimpleClass.new(“Veli”, 1986)
myClass5 = SimpleClass.new(“Metin”, 1989)
floatValue = 40.4
stringValue = “esiyo.net”

# Tüm nesneler üzrinden gezilerek SimpleClass tipinde olanların birth_year’lari bir arttırılıyor (gençleştiriliyor :) )
# veya object_id’si tanıdığım nesneler içerisinde ise ekrana yazdırıyorum.
# (aslında object space’i “Object” ile gezmek çok kÖtü bir yÖntem, fakat Örnek olduğu için kullanıyorum..)
ObjectSpace.each_object(Object) do |myClass|
if myClass.instance_of?(SimpleClass)
myClass.birth_year += 1
puts myClass
elsif [floatValue.object_id, stringValue.object_id].member?(myClass.object_id)
print “class = #{myClass.class}, object_id = #{myClass.object_id}, value = #{myClass}\n”
end
end
[/ruby]
programı çıktı olarak;
Private methods : calc_sequence
Public methods : name,name=,sequence,birth_year,birth_year=,age
Singleton methods : object_count
Parent classes : SimpleClass, Object, Kernel
class = String, object_id = 21357170, value = esiyo.net
5. Metin, 1990(18)
4. Veli, 1987(21)
3. Ali, 1986(22)
2. Sihaya, 1982(26)
1. Uordek, 1980(28)
class = Float, object_id = 21367840, value = 40.4
‘i üretir.

Daha fazla bilgi veya Örnek için nesneler aynı mı ? adlı yazımı inceleyebilirsiniz.

Kolay gelsin…

Share