Perl menawarkan lebih dari satu cara membangun objek, dan ekosistem modernnya menyediakan kerangka yang mengurangi kode penopang (boilerplate) berbasis bless. Topik ini menempatkan Moo dan Moose di dalam ekosistem tersebut, lalu memperkenalkan Object::Pad dengan sintaks class dan field yang dijalankan langsung pada sandbox. Setelah topik ini dibaca, pemilihan pendekatan objek untuk proyek baru dapat dipertimbangkan dengan dasar yang jelas.
Moo dan Moose di ekosistem modern#
Moo dan Moose adalah dua modul CPAN yang paling banyak digunakan untuk OOP pada Perl modern. Keduanya membentuk kelas, atribut, dan konstruktor dari deklarasi ringkas, sehingga penulis kelas tidak lagi menulis konstruktor bless secara manual. Moose merupakan kerangka objek yang lengkap dengan sistem tipe (type system) dan ekstensinya, sedangkan Moo menyediakan subset fitur Moose dengan pemasangan yang ringan dan antarmuka yang mirip. Proyek yang dimulai dengan Moo dapat naik ke Moose apabila fitur yang lebih lengkap benar-benar diperlukan.
Deklarasi atribut pada keduanya menggunakan kata has, dengan opsi is => 'rw' untuk aksesor baca-tulis dan opsi default untuk nilai bawaan. Konstruktor new dibentuk otomatis dan menerima pasangan atribut dan nilainya. Skrip berikut menunjukkan kelas Moo dengan atribut dan metode yang setara dengan model klasik.
use strict;
use warnings;
package SensorSuhu;
use Moo;
# atribut dengan aksesor baca-tulis dan nilai bawaan
has celcius => (is => 'rw', default => sub { 0 });
sub deskripsi {
my ($self) = @_;
return "Suhu " . $self->celcius . " derajat";
}
package main;
my $sensor = SensorSuhu->new(celcius => 24);
print $sensor->deskripsi, "\n";
$sensor->celcius(27);
print "Sekarang: ", $sensor->celcius, "\n";
print "Kelas : ", ref($sensor), "\n";Suhu 24 derajat
Sekarang: 27
Kelas : SensorSuhuKeluaran menunjukkan perilaku yang sama dengan model klasik, tetapi tidak ada satu baris bless pun pada kodenya. Aksesor celcius dibentuk dari deklarasi has, sehingga pembacaan dan penugasan nilai dilakukan melalui metode. Konstruktor yang dibentuk otomatis juga menerima pasangan atribut dan nilainya tanpa ditulis manual.
Object::Pad dengan class dan field#
Object::Pad adalah modul eksperimental yang membawa sintaks deklaratif ke inti bahasa melalui pragma use Object::Pad. Kelas dinyatakan dengan kata class, atributnya dengan field, dan metodenya dengan method. Modul ini menjadi tempat eksperimen menuju fitur objek bawaan use feature 'class' yang tersedia sejak Perl 5.38, sehingga bentuk penulisannya mengikuti arah masa depan bahasa.
Berbeda dengan model bless, atribut pada Object::Pad berupa variabel leksikal yang dideklarasikan dengan field dan hanya dapat diakses dari dalam metode kelasnya. Penanda :param menjadikan field sebagai parameter konstruktor, sedangkan nilai setelah tanda = menjadi nilai bawaannya. Metode dideklarasikan dengan method dan menerima $self secara otomatis, sehingga akses atribut berupa variabel $celcius dan bukan $self->{celcius}.
use strict;
use warnings;
use Object::Pad;
class Suhu {
# :param menjadikan field sebagai parameter konstruktor
field $celcius :param = 0;
field $riwayat = [];
method celcius { return $celcius; }
method ukur ($nilai) {
$celcius = $nilai;
push @$riwayat, $nilai;
return $self;
}
method maksimum {
return unless @$riwayat;
my $terbesar = $riwayat->[0];
for my $n (@$riwayat) {
$terbesar = $n if $n > $terbesar;
}
return $terbesar;
}
method deskripsi {
return "Suhu sekarang $celcius derajat";
}
}
package main;
my $suhu = Suhu->new(celcius => 24);
$suhu->ukur(27);
$suhu->ukur(25);
print $suhu->deskripsi, "\n";
print "Maksimum: ", $suhu->maksimum, "\n";
print "Kelas : ", ref($suhu), "\n";Suhu sekarang 25 derajat
Maksimum: 27
Kelas : SuhuKonstruktor new tidak ditulis sama sekali, tetapi Suhu->new(celcius => 24) tetap menerima parameternya karena penanda :param. Metode ukur mengubah field $celcius secara langsung dan menambahkan nilainya ke $riwayat, sedangkan metode maksimum menelusuri riwayat tersebut. Fungsi ref tetap mengembalikan nama kelasnya, yang berarti pemanggilan metode dari luar sama pada ketiga pendekatan.
Pewarisan juga didukung, tetapi letaknya berpindah dari array @ISA ke penanda pada deklarasi kelas, yaitu class Persegi :isa(PersegiPanjang) { }. Metode induk tetap dicari pada kelas yang disebut, dan pemanggilan versi induk dari dalam metode anak tetap menggunakan SUPER:: sebagaimana pada model klasik. Pengetahuan pewarisan pada model klasik dengan demikian tetap terpakai, hanya letak penulisannya yang berpindah.
Perbandingan singkat ketiga pendekatan#
Ketiga pendekatan menyelesaikan pekerjaan yang sama dengan tingkat penulisan yang berbeda. Perbedaan itu paling mudah diamati pada aspek yang dilihat setiap hari, yaitu cara kelas dinyatakan, cara atribut disimpan, dan siapa yang membentuk konstruktornya. Tabel berikut merangkum perbedaan yang paling menentukan pemilihan.
| Aspek | bless klasik | Moo | Object::Pad |
|---|---|---|---|
| Definisi kelas | package | package dengan use Moo | class Nama { } |
| Atribut | kunci hash | has dengan opsi | field leksikal |
| Konstruktor | ditulis manual | otomatis dari has | otomatis dari :param |
| Ketersediaan | inti bahasa | CPAN | CPAN, eksperimental |
Model klasik tetap menjadi fondasi karena tersedia di setiap instalasi Perl dan menjadi dasar kerja kerangka di atasnya. Moo dan Moose cocok untuk kode yang berdiri di atas ekosistem CPAN dan memerlukan kompatibilitas yang luas. Object::Pad menarik untuk proyek baru yang ingin membiasakan sintaks masa depan bahasa, dengan catatan status eksperimentalnya perlu dipertimbangkan terhadap kebutuhan stabilitas proyek.
Kesalahan umum#
Kesalahan pertama adalah menulis blok class tanpa pragma use Object::Pad; di atasnya. Perl menganggap class sebagai kata yang tidak dikenal dan program gagal pada saat kompilasi. Pastikan pragma tersebut berada sebelum deklarasi kelas yang pertama.
Kesalahan kedua adalah mencoba mengakses field sebagai hash, misalnya $suhu->{celcius}. Objek Object::Pad tidak menyimpan atribut pada hash, sehingga penulisan tersebut menghasilkan error Not a HASH reference saat berjalan. Akses atribut harus dilakukan melalui metode yang dideklarasikan dengan method.
Kesalahan ketiga adalah menganggap ketiga modul tersedia di mana pun. Skrip yang menggunakan Moo atau Object::Pad gagal dimuat pada instalasi Perl yang belum memasangnya, dengan pesan error Can't locate Moo.pm in @INC. Pasang modulnya terlebih dahulu atau gunakan model klasik untuk lingkungan yang tidak dapat ditambah pustakanya.
Ringkasan#
- Moo dan Moose membentuk kelas, atribut
has, dan konstruktor otomatis dari deklarasi ringkas, dengan Moose lebih lengkap dan Moo lebih ringan. - Object::Pad memperkenalkan sintaks
class,field, danmethod, serta menjadi jalur eksperimen menuju fitur objek bawaanuse feature 'class'Perl 5.38 ke atas. - Field berupa variabel leksikal yang hanya dapat diakses dari dalam metode, sedangkan
:parammenjadikannya parameter konstruktor. - Pemanggilan metode dari luar kelas sama pada ketiga pendekatan, sehingga pemanggil tetap menulis
$objek->metode.
Referensi#
- Moo — MetaCPAN
— Dokumentasi kerangka objek ringan dengan atribut
hasdan konstruktor otomatis. - Moose — MetaCPAN — Dokumentasi kerangka objek lengkap untuk OOP pada Perl modern.
- Object::Pad — MetaCPAN
— Dokumentasi pragma
classdanfieldyang menjadi dasar fitur objek bawaan Perl. - perlootut — Perl documentation — Tutorial objek Perl yang membahas pemilihan kerangka objek pada proyek nyata.