Lihat saja kode berorientasi objek dan semuanya kurang lebih mengikuti pola yang sama. Buat objek, panggil beberapa metode pada objek itu dan akses atribut objek itu. Tidak banyak lagi yang dapat Anda lakukan dengan objek kecuali meneruskannya sebagai parameter ke metode objek lain. Tapi yang kami perhatikan di sini adalah atribut.
Atributnya seperti variabel contoh Anda dapat mengakses melalui notasi titik objek. Sebagai contoh, nama orang akan mengakses nama seseorang. Demikian pula, Anda sering dapat menetapkan atribut seperti person.name = "Alice". Ini adalah fitur yang mirip dengan variabel anggota (seperti di C ++), tetapi tidak persis sama. Tidak ada yang istimewa di sini, atribut diimplementasikan dalam sebagian besar bahasa menggunakan "getter" dan "setter," atau metode yang mengambil dan mengatur atribut dari variabel instan.
Ruby tidak membuat perbedaan antara pengambil atribut dan setter dan metode normal. Karena metode fleksibel yang memanggil sintaksis, tidak ada perbedaan yang perlu dibuat. Sebagai contoh,
nama orang dan person.name () adalah hal yang sama, Anda memanggil nama metode dengan parameter nol. Yang satu tampak seperti pemanggilan metode dan yang lainnya tampak seperti atribut, tetapi keduanya benar-benar sama. Mereka berdua hanya memanggil nama metode. Demikian pula, nama metode apa pun yang berakhir dengan tanda sama dengan (=) dapat digunakan dalam penugasan. Pernyataan person.name = "Alice" benar-benar sama dengan person.name = (alice), meskipun ada spasi di antara nama atribut dan tanda sama dengan, itu masih hanya memanggil nama = metode.Anda dapat dengan mudah menerapkan atribut sendiri. Dengan mendefinisikan metode penyetel dan pengambil, Anda dapat menerapkan atribut apa pun yang Anda inginkan. Berikut beberapa contoh kode yang mengimplementasikan nama atribut untuk kelas orang. Ini menyimpan nama dalam a @nama variabel instan, tetapi nama tidak harus sama. Ingat, tidak ada yang istimewa dari metode ini.
Satu hal yang akan segera Anda perhatikan adalah bahwa ini banyak pekerjaan. Banyak mengetik hanya untuk mengatakan bahwa Anda ingin atribut bernama nama yang mengakses @nama variabel contoh. Untungnya, Ruby menyediakan beberapa metode kenyamanan yang akan menentukan metode ini untuk Anda.
Ada tiga metode dalam Modul kelas yang bisa Anda gunakan di dalam deklarasi kelas Anda. Ingatlah bahwa Ruby tidak membuat perbedaan antara runtime dan "waktu kompilasi," dan setiap kode di dalam deklarasi kelas tidak hanya dapat mendefinisikan metode tetapi juga memanggil metode. Memanggil attr_reader, attr_writer dan attr_accessor metode akan, pada gilirannya, menentukan setter dan getter yang kita definisikan sendiri di bagian sebelumnya.
Itu attr_reader Metode tidak seperti apa yang akan dilakukan. Dibutuhkan sejumlah parameter simbol dan, untuk setiap parameter, mendefinisikan metode "pengambil" yang mengembalikan variabel instance dari nama yang sama. Jadi, kita bisa mengganti nama metode pada contoh sebelumnya dengan attr_reader: name.
Demikian pula halnya dengan attr_writer metode mendefinisikan metode "setter" untuk setiap simbol yang diteruskan ke sana. Perhatikan bahwa tanda sama dengan tidak harus menjadi bagian dari simbol, hanya nama atribut. Kita bisa mengganti nama = metode dari contoh sebelumnya dengan panggilan ke attr_writier: name.
Dan, seperti yang diharapkan, attr_accessor melakukan pekerjaan keduanya attr_writer dan attr_reader. Jika Anda memerlukan penyetel dan pengambil untuk atribut, sudah menjadi kebiasaan untuk tidak memanggil kedua metode secara terpisah, dan sebaliknya memanggil attr_accessor. Kita bisa ganti kedua itu nama dan nama = metode dari contoh sebelumnya dengan satu panggilan ke attr_accessor: name.
Mengapa Anda harus mendefinisikan setter secara manual? Mengapa tidak menggunakan attr_ * metode setiap waktu? Karena mereka merusak enkapsulasi. Enkapsulasi adalah prinsip yang menyatakan tidak ada entitas luar yang memiliki akses tidak terbatas ke kondisi internal Anda benda. Semuanya harus diakses menggunakan antarmuka yang mencegah pengguna merusak keadaan internal objek. Dengan menggunakan metode di atas, kami telah membuat lubang besar di dinding enkapsulasi kami dan membiarkan apa pun ditetapkan untuk nama, bahkan nama yang jelas tidak valid.
Satu hal yang sering Anda lihat adalah itu attr_reader akan digunakan untuk dengan cepat mendefinisikan pengambil, tetapi penyetel kustom akan ditentukan karena keadaan internal objek sering ingin menjadi Baca langsung dari keadaan internal. Setter kemudian didefinisikan secara manual dan melakukan pengecekan untuk memastikan bahwa nilai yang ditetapkan masuk akal. Atau, mungkin lebih umum, tidak ada setter yang didefinisikan sama sekali. Metode lain dalam fungsi kelas mengatur variabel instance di belakang pengambil dengan beberapa cara lain.
Kami sekarang dapat menambahkan usia dan menerapkan dengan benar a nama atribut. Itu usia atribut dapat diatur dalam metode konstruktor, baca menggunakan usia getter tetapi hanya dimanipulasi menggunakan have_birthday metode, yang akan menambah usia. Itu nama atribut memiliki pengambil normal, tetapi setter memastikan nama dikapitalisasi dan dalam bentuk Nama depan Nama Belakang.