Ruby, aşağıdaki gibi anahtarlar kullanarak örnek değişkenleri paylaşmanın bu kullanışlı ve kullanışlı yoluna sahiptir
attr_accessor :var
attr_reader :var
attr_writer :var
Basitçe attr_accessor
kullanabilecekken neden attr_reader
veya attr_writer
seçeyim ki? Performans gibi bir şey mi var (ki bundan şüpheliyim)? Sanırım bir nedeni var, aksi takdirde böyle anahtarlar yapmazlardı.
Kodunuzu okuyan birine amacınızı iletmek için farklı erişimcileri kullanabilir ve genel API'leri nasıl çağrılırsa çağrılsın doğru şekilde çalışacak sınıflar yazmayı kolaylaştırabilirsiniz.
class Person
attr_accessor :age
...
end
Burada, yaşı hem okuyabildiğimi hem de yazabildiğimi görebiliyorum.
class Person
attr_reader :age
...
end
Burada, sadece yaşı okuyabileceğimi görebiliyorum. Bu sınıfın kurucusu tarafından ayarlandığını ve bundan sonra sabit kaldığını düşünün. Eğer yaş için bir mutator (yazar) olsaydı ve sınıf bir kez ayarlandıktan sonra yaşın değişmeyeceği varsayılarak yazılsaydı, o zaman bu mutatoru çağıran koddan kaynaklanan bir hata oluşabilirdi.
Peki ama perde arkasında neler oluyor?
Eğer yazarsan:
attr_writer :age
Bu şu anlama geliyor:
def age=(value)
@age = value
end
Eğer yazarsan:
attr_reader :age
Bu şu anlama geliyor:
def age
@age
end
Eğer yazarsan:
attr_accessor :age
Bu şu anlama geliyor:
def age=(value)
@age = value
end
def age
@age
end
Bunu bilerek, işte bunu düşünmenin başka bir yolu: Eğer attr_... yardımcılarına sahip olmasaydınız ve erişimcileri kendiniz yazmak zorunda kalsaydınız, sınıfınızın ihtiyaç duyduğundan daha fazla erişimci yazar mıydınız? Örneğin, age'nin yalnızca okunması gerekiyorsa, yazılmasına izin veren bir yöntem de yazar mıydınız?
Bir nesnenin tüm niteliklerinin sınıf dışından doğrudan ayarlanması amaçlanmamıştır. Tüm örnek değişkenleriniz için yazarlara sahip olmak genellikle zayıf kapsüllemenin bir işaretidir ve sınıflarınız arasında çok fazla bağlantı kurduğunuza dair bir uyarıdır.
Pratik bir örnek olarak: Öğeleri konteynerlerin içine koyduğunuz bir tasarım programı yazdım. Öğenin attr_reader :container
özelliği vardı, ancak bir yazar sunmak mantıklı değildi, çünkü öğenin kapsayıcısının değişmesi gereken tek zaman yeni bir kapsayıcıya yerleştirildiği zamandır, bu da konumlandırma bilgisi gerektirir.
Örnek değişkenlerinizin her zaman sınıf dışından tamamen erişilebilir olmasını istemezsiniz. Bir örnek değişkene okuma erişimine izin vermenin mantıklı olduğu, ancak yazmanın mantıklı olmayabileceği birçok durum vardır (örneğin, verileri salt okunur bir kaynaktan alan bir model). Bunun tersini istediğiniz durumlar da vardır, ancak aklıma gelenler arasında yapmacık olmayanlar yok.