Ruby memiliki cara praktis dan nyaman ini untuk membagikan variabel instan dengan menggunakan tombol suka
attr_accessor :var
attr_reader :var
attr_writer :var
Mengapa saya memilih attr_reader
atau attr_writer
jika saya bisa menggunakan saja attr_accessor
? Apakah ada sesuatu seperti kinerja (yang saya ragu)? Saya kira ada alasannya, kalau tidak mereka tidak akan membuat kunci seperti itu.
Jawaban:
Anda dapat menggunakan pengakses yang berbeda untuk mengomunikasikan niat Anda kepada seseorang yang membaca kode Anda, dan membuatnya lebih mudah untuk menulis kelas yang akan bekerja dengan benar tidak peduli bagaimana API publik mereka dipanggil.
Di sini, saya dapat melihat bahwa saya dapat membaca dan menulis usia.
Di sini, saya dapat melihat bahwa saya hanya dapat membaca umur. Bayangkan bahwa itu diatur oleh konstruktor dari kelas ini dan setelah itu tetap konstan. Jika ada mutator (penulis) untuk usia dan kelas ditulis dengan asumsi usia itu, setelah diatur, tidak berubah, maka bug dapat dihasilkan dari kode yang memanggil mutator itu.
Tapi apa yang terjadi di balik layar?
Jika Anda menulis:
Itu diterjemahkan ke dalam:
Jika Anda menulis:
Itu diterjemahkan ke dalam:
Jika Anda menulis:
Itu diterjemahkan ke dalam:
Mengetahui hal itu, inilah cara lain untuk memikirkannya: Jika Anda tidak memiliki pembantu, dan harus menulis sendiri para pengakses, apakah Anda akan menulis pengakses yang lebih banyak dari yang dibutuhkan oleh kelas Anda? Misalnya, jika usia hanya perlu dibaca, apakah Anda juga menulis metode yang memungkinkannya untuk ditulis?
sumber
attr_reader :a
vs.def a; return a; end
confreaks.net/videos/…attr_reader
accesor yang ditentukan membutuhkan 86% dari waktu yang diakses oleh accessor yang ditentukan secara manual. Untuk Ruby 1.9.0, pengakses yangattr_reader
ditentukan mengambil 94% dari waktu yang diakses pengakses secara manual. Namun, dalam semua pengujian saya, pengakses cepat: pengakses membutuhkan sekitar 820 nanodetik (Ruby 1.8.7) atau 440 nanodetik (Ruby 1.9). Pada kecepatan itu, Anda harus memanggil pengakses ratusan kali untuk manfaat kinerjaattr_accessor
untuk meningkatkan runtime keseluruhan bahkan dengan satu detik.attr_accessor :a, :b
Semua jawaban di atas benar;
attr_reader
danattr_writer
lebih nyaman untuk menulis daripada mengetik secara manual metode mereka adalah singkatan. Selain itu mereka menawarkan kinerja yang jauh lebih baik daripada menulis definisi metode sendiri. Untuk info lebih lanjut lihat slide 152 dan seterusnya dari pembicaraan ini ( PDF ) oleh Aaron Patterson.sumber
Tidak semua atribut dari suatu objek dimaksudkan untuk diatur secara langsung dari luar kelas. Memiliki penulis untuk semua variabel instan Anda biasanya merupakan tanda enkapsulasi yang lemah dan peringatan bahwa Anda terlalu banyak memasukkan penggabungan antar kelas Anda.
Sebagai contoh praktis: Saya menulis program desain di mana Anda meletakkan barang-barang di dalam wadah. Item itu sudah ada
attr_reader :container
, tetapi tidak masuk akal untuk menawarkan penulis, karena satu-satunya waktu kontainer item harus berubah adalah ketika itu ditempatkan di yang baru, yang juga memerlukan informasi posisi.sumber
Penting untuk dipahami bahwa pengakses membatasi akses ke variabel, tetapi bukan kontennya. Dalam ruby, seperti dalam beberapa bahasa OO lainnya, setiap variabel adalah penunjuk ke instance. Jadi, jika Anda memiliki atribut ke Hash, misalnya, dan Anda menetapkannya menjadi "read only" Anda selalu dapat mengubah kontennya, tetapi bukan konten pointer. Lihat ini:
Seperti yang Anda lihat adalah mungkin menghapus pasangan kunci / nilai dari Hash @a, seperti menambahkan kunci baru, mengubah nilai, dan sebagainya. Tetapi Anda tidak dapat menunjuk ke objek baru karena merupakan variabel instan hanya baca.
sumber
Anda tidak selalu ingin variabel instan Anda dapat diakses sepenuhnya dari luar kelas. Ada banyak kasus di mana memungkinkan akses baca ke variabel instan masuk akal, tetapi menulisnya mungkin tidak (misalnya model yang mengambil data dari sumber baca-saja). Ada kasus-kasus di mana Anda menginginkan yang sebaliknya, tetapi saya tidak bisa memikirkan yang tidak dibuat-buat di atas kepala saya.
sumber