Soru Tarihi:
Perl'de OOP, paketler (package) temelli ve bless fonksiyonu ile referansların bağlanması yoluyla gerçekleştirilir. Miras alma, Perl'in yöntemleri arayacağı paketleri otomatik olarak belirleyen @ISA dizisi sayesinde sağlanır. Arama mekanizması, MRO (method resolution order) olarak bilinen bir yapı ile uygulanır.
Sorun:
@ISA dizisinin kaotik yönetimi ve SUPER'ın kullanımının yöntem arama sırasını anlamadan yapılması sıklıkla hatalara, çift çağrılara veya istenen işlevselliğin yeniden tanımlanmasının imkansız hale gelmesine neden olur. AUTOLOAD kullanımı, sonsuz arama döngüsü tuzaklarından kaçınmak için dikkat gerektirir.
Çözüm:
Kod örneği:
package Animal; sub speak { print "Animal speaks "; } package Dog; our @ISA = qw(Animal); sub speak { print "Dog barks! "; shift->SUPER::speak(); # ebeveyn metodunu çağrısı } my $dog = bless {}, 'Dog'; $dog->speak;
Temel özellikler:
Eğer miras zincirinde aynı metoda sahip birden fazla ebeveyn paketi varsa, hangisi çağrılır?
Arama soldan sağa (yani, @ISA'daki ilan sırasına göre) yapılır, ilk bulunan yöntem çağrılır.
Eğer belirli bir yöntem miras ağacında yoksa ve AUTOLOAD sadece ebeveynlerden birinde tanımlıysa ne olur?
Perl yalnızca yöntem arama zincirinde AUTOLOAD'ı ilk bulan sınıfı çağırır. Diğer AUTOLOAD'lar, @ISA'da daha önce karşılaşmazlarsa çalışmayacaktır.
Yöntem zincirinin arama sırasını dinamik olarak değiştirmek mümkün mü?
Teknik olarak @ISA dizisini çalışma zamanında değiştirmek mümkündür, ancak bu kırılganlığa ve zor izlenebilir hatalara yol açar. Bu yaklaşım yalnızca özel durumlar için önerilir.
Aynı isimdeki yöntemlere sahip birden çok ebeveyn sınıfı kullanılıyor, @ISA'daki sıraları öngörülemez bir şekilde manuel olarak değişiyor, yöntemler SUPER'ı çağırıyor, bu da sonsuz bir rekursiyona yol açıyor.
Artıları:
Eksileri:
Sadece @ISA'yı açıkça belirterek değişiklikler ve gerektiğinde çoklu miras için mro::Concise ya da Class::C3 gibi özel modüller kullanımı.
Artıları:
Eksileri: