apakah ini maksud dari desain Raku?
Wajar untuk mengatakan bahwa Raku tidak sepenuhnya tidak terbuka di bidang ini. Pertanyaan Anda menyentuh dua tema dalam desain Raku, yang sama-sama layak untuk dibahas.
Raku memiliki nilai l kelas satu
Raku memanfaatkan banyak nilai-l sebagai hal kelas satu. Ketika kita menulis:
has $.x is rw;
Metode yang dihasilkan adalah:
method x() is rw { $!x }
Di is rw
sini menunjukkan bahwa metode mengembalikan nilai-l - yaitu, sesuatu yang dapat ditugaskan. Demikian ketika kita menulis:
$obj.x = 42;
Ini bukan gula sintaksis: itu benar-benar panggilan metode, dan kemudian operator penugasan diterapkan untuk hasilnya. Ini berhasil, karena pemanggilan metode mengembalikan Scalar
wadah atribut, yang kemudian dapat ditugaskan ke. Seseorang dapat menggunakan binding untuk membagi ini menjadi dua langkah, untuk melihat itu bukan transformasi sintaksis sepele. Sebagai contoh, ini:
my $target := $obj.x;
$target = 42;
Akan menugaskan ke atribut objek. Mekanisme yang sama ini ada di balik berbagai fitur lain, termasuk penugasan daftar. Sebagai contoh, ini:
($x, $y) = "foo", "bar";
Bekerja dengan membangun List
wadah berisi $x
dan $y
, dan kemudian operator penugasan dalam hal ini iterates setiap sisi berpasangan untuk melakukan penugasan. Ini berarti kita dapat menggunakan rw
pengakses objek di sana:
($obj.x, $obj.y) = "foo", "bar";
Dan itu semua secara alami bekerja. Ini juga merupakan mekanisme di balik penugasan pada irisan array dan hash.
Satu juga dapat digunakan Proxy
untuk membuat wadah bernilai-l di mana perilaku membaca dan menulis itu di bawah kendali Anda. Dengan demikian, Anda bisa memasukkan aksi samping ke dalamSTORE
. Namun...
Raku mendorong metode semantik atas "setter"
Ketika kami menggambarkan OO, istilah seperti "enkapsulasi" dan "menyembunyikan data" sering muncul. Gagasan utama di sini adalah bahwa model keadaan di dalam objek - yaitu, cara yang dipilihnya untuk merepresentasikan data yang diperlukan untuk mengimplementasikan perilakunya (metode) - bebas untuk berevolusi, misalnya untuk menangani persyaratan baru. Semakin kompleks objek, semakin membebaskan ini menjadi.
Namun, getter dan setter adalah metode yang memiliki koneksi implisit dengan negara. Meskipun kami mungkin mengklaim bahwa kami mencapai penyembunyian data karena kami memanggil metode, tidak mengakses keadaan secara langsung, pengalaman saya adalah bahwa kami dengan cepat berakhir di tempat di mana kode luar membuat urutan panggilan setter untuk mencapai operasi - yang merupakan suatu bentuk iri fitur anti-pola. Dan jika kita melakukan itu , cukup yakin kita akan berakhir dengan logika di luar objek yang melakukan campuran antara pengambil dan penyetel operasi untuk mencapai operasi. Sungguh, operasi ini seharusnya diekspos sebagai metode dengan nama yang menggambarkan apa yang sedang dicapai. Ini menjadi lebih penting jika kita berada dalam pengaturan bersamaan; objek yang dirancang dengan baik seringkali cukup mudah untuk dilindungi pada batas metode.
Yang mengatakan, banyak penggunaan class
benar-benar jenis catatan / produk: mereka ada untuk hanya mengelompokkan sekelompok item data. Bukan kebetulan bahwa .
sigil tidak hanya menghasilkan accessor, tetapi juga:
- Memilih atribut agar diatur oleh logika inisialisasi objek default (yaitu, a
class Point { has $.x; has $.y; }
dapat dipakai sebagai Point.new(x => 1, y => 2)
), dan juga menjadikannya dalam .raku
metode dumping.
- Memilih atribut ke
.Capture
objek default , yang berarti kita dapat menggunakannya dalam merusak (misalnya sub translated(Point (:$x, :$y)) { ... }
).
Mana hal-hal yang Anda inginkan jika Anda menulis dengan gaya yang lebih prosedural atau fungsional dan menggunakan class
sebagai sarana untuk menentukan jenis rekaman.
Desain Raku tidak dioptimalkan untuk melakukan hal-hal pintar di setter, karena itu dianggap hal yang buruk untuk dioptimalkan. Ini melampaui apa yang diperlukan untuk tipe rekaman; dalam beberapa bahasa kita bisa berdebat kita ingin melakukan validasi dari apa yang ditugaskan, tetapi di Raku kita dapat beralih ke subset
tipe untuk itu. Pada saat yang sama, jika kita benar-benar melakukan desain OO, maka kita menginginkan API perilaku yang berarti yang menyembunyikan model negara bagian, daripada berpikir dalam kaitannya dengan pengambil / penentu, yang cenderung mengarah pada kegagalan untuk berkolokasi. data dan perilaku, yang merupakan inti dari melakukan OO.