Arsip mwmag[Files]  [Up]© 2002 PT Masterweb Media

Tutorial Perl Bagian 5: Referensi dan OOP

Referensi di Perl

Package

Modul

Mengenal Pemrograman Berorientasi Objek di Perl

Menginstal Modul GD

Memakai Modul GD di Perl

Penutup

Daftar gambar

  1. Hasil contoh penggunaan modul GD
Tutorial Perl Bagian 5:

Referensi dan OOP

Saat ini hampir semua bahasa (Pascal, C, dan PHP misalnya) sudah memiliki ekstensi yang memungkinkan pemrograman berorientasi objek dilakukan dalam bahasa itu. Perl juga tidak luput dari tren itu. Perl tidak dirancang sebagai bahasa berorientasi objek, namun dengan beberapa hack di versi 5, Anda dapat melakukan pemrograman berorientasi objek di Perl.

Apakah Anda butuh objek? Mungkin tidak. Apa yang bisa Anda program dalam paradigma berorientasi objek juga bisa Anda program dalam paradigma prosedural (atau bahkan fungsional). Namun saat ini OO sudah menjadi tren; banyak modul OO yang menarik yang tidak bisa dipakai jika Anda tidak punya pemahaman sama sekali mengenai objek.

Untuk belajar OO di Perl, Anda harus mengerti tiga konsep dasar di Perl yaitu, referensi, subrutin, dan modul/package. Subrutin sudah dibahas di tutorial edisi ketiga, dan cara memakai modul juga sudah dibahas di edisi ke-3 dan ke-4. Sebelum melangkah ke objek, akan saya perkenalkan dulu referensi di Perl dan cara membuat modul dan package.

Referensi di Perl

Saat ini Anda sudah mengenal tiga jenis tipe variabel di Perl, yaitu skalar, array, dan hash. Namun Perl juga mengenal suatu tipe skalar yang khusus yang dinamakan dengan referensi. Jika suatu variabel menampung suatu nilai, maka referensi berisi alamat atau penunjuk ke suatu nilai. Jika dianalogikan dengan sebuah buku, variabel berisi nilai seperti sebuah halaman buku berisi informasi di dalamnya, sedangkan referensi merupakan petunjuk, seperti sebuah halaman buku yang hanya berisi “lihat halaman 2706”.

Tapi apa gunanya referensi? Berguna sekali. Di Perl, kita tidak bisa membentuk struktur data rumit tanpa adanya referensi. Saya akan membahas referensi untuk struktur data yang rumit di edisi yang lain, untuk saat ini saya hanya akan menunjukkan apa itu referensi dan kegunaannya dalam subrutin yang memerlukan pass by reference.

Anda akan lebih mudah memahami referensi dari contoh:

$nama = "feynman";
$n = \$nama;
print $n;

Hasil program di atas, mungkin seperti ini:

SCALAR(0x8104b8c)

Angka di dalam kurung tidak selalu sama, tergantung lokasi memori variabel $nama di proses program Perl. Variabel $n berisi alamat (dan tipe) dari variabel $nama. Operator untuk mengambil alamat suatu variabel adalah \ (backslash). Untuk mengakses nilai yang ditunjuk oleh $nama, kita melakukannya dengan:

print ${$n};

atau bisa juga dengan:

print $$n;

Jika kita mengubah nilai $$n, ternyata kita juga mengubah nilai $nama, contoh:

$nama = "feynman";
$n = \$nama;
print "Sebelum: ${$n}\n";
$$n="richard";
print "Sesudah: $nama\n";

potongan kode di atas akan mencetak tulisan:

Sebelum: feynman
Sesudah: richard

Kenapa itu bisa terjadi? Akan saya coba jelaskan dengan menggunakan analogi buku tadi. Jika Anda hanya memberikan salinan variabel seperti ini:

$a = 1982;
$b = $a;

maka $b akan berisi nilai $a, sama seperti Anda memberikan salinan sebuah halaman buku ke seseorang. Maka jika Anda mengubah nilai $b, seperti ini:

$b = 1980;

nilai $a tetap 1982, karena yang diubah adalah salinan variabel (seperti jika salinan halaman buku itu diubah, halaman aslinya tidak akan berubah). Tapi jika yang diberikan ke orang lain adalah petunjuk di mana informasi tersebut berada (referensi), misalnya halaman 1705, maka orang yang diberi informasi bisa mengubah isi halaman buku tersebut karena tahu letaknya.

Referensi tidak hanya menunjuk ke variabel skalar, tapi juga ke variabel array atau hash. Untuk array, Anda bisa melakukan ini:

@superhero = ("spiderman", "superman", "batman");
$super = \@superhero;

Jika Anda hanya perlu referensi ke suatu array, Anda tidak perlu membuat dulu variabel arraynya, Anda bisa menggunakan notasi [ isi list ] jadi yang di atas bisa disingkat menjadi:

$super = ["spiderman", "superman", "batman"];

untuk mengakses nilai array tersebut, Anda bisa melakukannya seperti ini:

@hero = @$super;

untuk mengakses elemennya, Anda bisa menggunakan salah satu cara ini:

$spiderman = ${$super}[0];
$superman = $super->[1];

Kita lewatkan dulu pembahasan mengenai array dua dimensi untuk edisi ini. Dan mari melangkah ke hash. Anda bisa melakukan hal yang sama terhadap hash, seperti yang Anda lakukan terhadap array. Bedanya adalah kalau untuk array kita memakai operator [...], maka untuk membuat referensi ke hash tidak bernama (anonim), Anda melakukannya dengan notasi {...} seperti ini:

$warna = {
"bunga" => "merah",
"bola" => "putih"
};

Dan tentunya referensi ke hash diakses dengan:

%lili = %{$bcd};

Dan bahkan referensi ke suatu subrutin dapat dibuat, seperti ini:

sub test {
print "test";
}
$a = \&test;

untuk memanggil subrutin tersebut:

&$a();

Pass by Value dan Pass by Reference

Anda sudah belajar bahwa di Perl, parameter untuk suatu subrutin diakses dengan array @_. Namun di edisi yang lalu saya hanya memberi contoh jika parameter yang dilewatkan ke subrutin adalah nilai skalar. Jika nilai yang dilewatkan adalah list atau hash, hasilnya mungkin tidak akan seperti yang Anda harapkan, lihat contoh ini:

sub hello {
my ($greet, $name) = @_;
print "Selamat $greet, $name\n";
}
hello("Pagi", "Donna");
@l = ("Malam", "Lala");
hello(@l);
hello("Siang", @l);
$waktukerja{"yuni"}="malam";
hello(%waktukerja);

Output program tersebut adalah:

Selamat Pagi, Donna
Selamat Malam, Lala
Selamat Siang, Malam
Selamat yuni, malam

Seperti yang Anda lihat, Perl akan “mendangkalkan” list ketika dilewatkan ke suatu subrutin.

@l=("romeo”, ”juliet");
hello(@l);

sama saja dengan

hello($l[0], $l[1]);

Semua parameter akan diberikan ke @_ secara berurutan. Hal ini berlaku baik untuk hash, array, skalar, ataupun gabungan dari semua itu. Lalu masalahnya? Masalahnya adalah Anda tidak bisa memberikan array atau hash ke suatu subrutin dalam bentuk yang sebenarnya.

Perl hanya mendukung parameter subrutin berupa skalar, namun seperti yang kita ketahui, ada suatu tipe skalar khusus yang disebut referensi, kita bisa menggunakan sifat referensi untuk membuat subrutin yang bisa mengakses dan memodifikasi array atau hash yang kita berikan. Cara melewatkan parameter seperti itu (memakai referensi) disebut pass by reference, sedangkan jika yang dilewatkan hanya nilainya maka disebut pass by value.

Lihat contoh ini:

sub add_me {
my ($arr) = @_;
push @$arr, "me";
}
@a = qw(joe nitnotz);
add_me(\@a);
print join(" ", @a);

Subrutin add_me akan menambahkan elemen “me” ke array, sehingga output program adalah:

joe nitnotz me

Jika Anda membuka kembali tutorial bagian 2, Anda akan mendapati bagaimana cara mendapatkan daftar user di Unix. Sebagai latihan Anda bisa memanfaatkan kode itu untuk membuat subrutin yang akan mengisikan daftar user yang ada pada sistem ke sebuah list. Sehingga Anda bisa melakukan seperti ini:

get_user_list(\@users);
foreach (@users) {
#lakukan sesuatu di sini
}

Subrutin semacam itu bisa Anda pakai di berbagai program yang berhubungan dengan administrasi sistem.

Package

Anda pasti punya lebih dari satu teman yang bernama Agus atau Budi. Biasanya untuk membedakannya Anda harus menambahkan suatu atau lebih kata untuk membedakannya, entah itu nama lengkap (Budi Kurniawan, Budi Setiawan), kata sifat (Budi kurus, Budi gemuk), nama tempat (Agus Cimahi, Agus Jakarta), atau apapun juga. Sama halnya dengan nama di dunia nyata, nama variabel dan subrutin yang ada di program Anda kemungkinan bisa bentrok dengan nama yang ada di program lain. Untuk mengatasi masalah tersebut, di Perl diciptakan package.

Pernyataan package menyatakan bahwa suatu unit kompilasi berada dalam namespace tertentu. Contohnya:

{
package testpack;
$a = "4";
print "nilai a: $a\n";
}
$a=2;
print "nilai a ini : $a\n";
print "nilai a dari sini :$testpack::a\n";

Pernyataan package berlaku dari awal deklarasi package sampai akhir scope yang melingkupinya. Jika pada potongan program di atas tidak diberi tanda kurung kurawal, maka scope package adalah dari awal pernyataan package sampai akhir file

Output program adalah:

nilai a: 4
nilai a ini :2
nilai a dari sini :4

Dalam package, untuk menyebut suatu nilai variabel, atau memanggil suatu subrutin, kita tidak perlu menyebut nama packagenya dengan lengkap, sedangkan di luar package kita perlu menyebutnya dengan lengkap (tapi nanti Anda bisa melihat bahwa ini tidak sepenuhnya benar). Sama seperti Anda tidak perlu menyebut nama lengkap budi teman Anda jika dia serumah dengan Anda, namun perlu menyebut dengan lengkap nama (atau mungkin informasi lainnya) jika sedang bermaksud menyebut budi yang lain.

Sebenarnya semua program Perl berada dalam suatu package, jika tidak disebutkan maka nama package yang dipakai secara otomatis adalah main, jadi pernyataan $a = 2 di atas bisa ditulis juga sebagai $main::a.

Modul

Sebuah modul hanyalah sekumpulan fungsi-fungsi yang berada dalam sebuah file dengan nama file sama dengan nama packagenya. Modul digunakan agar suatu kode program dapat dipakai lagi di program lain (reuseable). Anda sudah belajar bagaimana memakai modul, sekarang saatnya Anda belajar membuat modul. Saat ini kita hanya akan membuat sebuah modul sederhana. Buatlah direktori yo yang isinya adalah file hello.pm.

package yo::hello;
require Exporter;
@ISA=qw(Exporter);
@EXPORT = qw(&hello_world);
@EXPORT_OK = qw(&greet);
sub hello_world {
print "Hello, World\n";
}
sub greet {
my ($waktu, $nama)=@_;
print "Selamat $waktu, $nama\n";
}

dan di direktori tempat direktori yo berada, buatlah file dengan isi seperti ini:

use yo::hello;
hello_world();

hanya ada lima baris di hello.pm yang perlu penjelasan. Pertama:

package yo::hello;

menyatakan bahwa nama package kita adalah yo::hello.

require Exporter;
@ISA=qw(Exporter);

Dua baris ini menyatakan bahwa untuk mengekspor modul kita, kita menggunakan modul Exporter. Ada cara manual untuk melakukannya, tapi cara termudah adalah dengan menggunakan modul Exporter.

@EXPORT = qw(&hello_world);
@EXPORT_OK = qw(&greet);

@EXPORT menyatakan daftar fungsi yang kita ekspor secara otomatis, sedangkan @EXPORT_OK menyatakan daftar fungsi yang boleh diekspor. Untuk memakai fungsi yang ada di @EXPORT kita tidak perlu menambahkan apa-apa di use namamodul, tapi jika kita ingin memakai fungsi atau variabel yang ada di @EXPORT_OK, kita perlu menyebut namanya, seperti ini:

use yo::hello qw (greet);

Mengenal Pemrograman Berorientasi Objek di Perl

Tutorial ini—setidaknya di edisi ini—hanya akan membahas mengenai dasar-dasar OO di Perl. Konsep OO hanya akan dijelaskan sedikit, karena konsep OO tidak sederhana (ada banyak buku yang bisa Anda beli untuk lebih memahami konsep OO baik secara umum, maupun khusus untuk Perl). Tutorial di edisi ini hanya akan menjelaskan konsep objek agar Anda cukup bisa memakai modul OO di Perl.

Ada dua konsep paling penting yang harus Anda pahami dalam pemrograman OO yaitu objek dan kelas. Saya akan menjelaskan objek dengan analogi, jika mobil adalah sebuah objek, maka cetak biru dari mobil tersebut adalah sebuah kelas, jika objek adalah variabel, maka kelas adalah tipe variabel tersebut. Di Perl, sebuah kelas adalah sebuah package, dan subrutin di dalamnya merupakan metode.

Pertama, kita perlu memahami sedikit notasi. Untuk memanggil sebuah subrutin dalam suatu package (atau metode dalam kelas), kita dapat memakai notasi ->, jadi:

yo::hello::hello_world()

dapat juga ditulis:

yo::hello->hello_world();

bahkan seperti ini juga bisa:

$name="yo::hello";
$name->hello_world();

Banyak hal yang lebih mudah dijelaskan menggunakan contoh. Demikian juga dalam hal menjelaskan pemrograman objek. Misalkan kita punya sebuah package seperti ini (package ini juga sekaligus adalah sebuah kelas).

{
package Robot;
sub ngomong {
my $self = shift;
print "Hello, namaku $$self\n";
}
}

Di dalam package tersebut, didefinisikan sebuah subrutin (atau metode kalau package dipandang sebagai kelas) yang mencetak parameter pertama yang diberikan kepadanya. Variabel $self diisi dengan @_[0] dengan shift. Tepatnya, subrutin itu mencetak nilai yang ditunjuk oleh parameter pertama (parameter pertama haruslah sebuah referensi ke suatu objek).

Kita bisa memanggil subrutin itu seperti ini:

$namaku = "hiroko";
$robotku = \$namaku;
Robot->ngomong($robotku)

Sekarang perhatikan potongan program berikut:

$namaku = "hiroko";
$robotku = \$namaku;
bless $robotku, Robot;
$robotku->ngomong();

Dua baris pertama Anda sudah dapat mengerti, $robotku adalah referensi ke $namaku. Operator bless merupakan operator khusus yang gunanya adalah menyimpan informasi mengenai suatu package ke suatu benda (skalar, array, hash, dll) yang ditunjuk oleh referensi. Setelah di-bless, maka referensi $robotku menunjuk ke sebuah instans dari kelas Robot (Robot adalah kelas, $robotku penunjuk ke objek).

Ketika baris $robotku->ngomong() dieksekusi, maka Perl akan melihat bahwa $robotku adalah referensi yang sudah di-bless ke package Robot, sehingga akan mencari metode atau subrutin ngomong() di package Robot, dan memanggil subrutin itu dengan memberikan referensi yang di-bless (yaitu $robotku) sebagai parameter pertama untuk subrutin ngomong().

Tentunya tidak efisien jika untuk membuat sebuah instans dari kelas robot, Anda harus melakukan semua langkah itu. Biasanya setiap kelas akan memiliki metode untuk membuat instans dirinya, jika dalam package Robot ditambahkan subrutin ini:

sub baru {
my $class = shift;
my $name = shift;
bless \$name, $class;
}

Maka kita bisa melakukan:

$robotmu = Robot->baru("Spiderman");
$robotmu->ngomong();

Perl juga mengizinkan hal ini dilakukan:

$robotmu = baru Robot("WonderWoman");
ngomong $robotmu;

Nama metode boleh mendahului nama kelas atau instans kelas.

Mungkin Anda masih bingung apa itu kelas dan apa itu objek. Sederhananya begini, kelas adalah package. Sebuah referensi bisa dibless ke suatu package. Referensi yang dibless itu sekarang menunjuk ke sebuah objek. Dan yang saya jelaskan di atas hanyalah beberapa notasi yang membuat Anda bisa mengerti bagaimana berurusan dengan objek.

Pembahasan mendalam mengenai objek tidak akan dilakukan di edisi ini, namun dengan berbekal pengetahuan di atas, Anda sudah bisa memanfaatkan aneka modul OO. Dalam bagian berikutnya Anda bisa melihat contoh pemakaian library GD untuk menggambar grafik (menjadi sebuah file) di Perl.

Menginstal Modul GD

GD merupakan library grafik yang memungkinkan kita membuat grafik dari dalam program. Modul ini sangat terkenal untuk membuat gambar dinamis di Web, namun penggunaan modul ini tentunya tidak sebatas di Web saja. Modul GD tidak termasuk dalam modul standar Perl, jadi Anda harus menginstalnya dulu.

Jika Anda memakai ActivePerl , Anda bisa memakai Perl package manager. Hubungkan diri Anda dengan Internet. Ketikkan ppm di command prompt, Anda akan masuk ke prompt ppm, ketikkan:

install GD

jawab y, tekan Enter, lalu tunggu sampai paketnya didownload. Jika Anda memakai distribusi Perl standar, ketikkan:

perl –e shell –MCPAN

Jika Anda baru pertama kali memakai shell modul CPAN, Anda akan berhadapan dengan banyak pertanyaan. Anda bisa menjawab Enter saja untuk setiap pertanyaan dan menunggu. Anda juga bisa melihat di MWCD 01 mengenai cara membuat mirror CPAN secara lokal.

Dari promptnya, Anda bisa menginstal GD dengan mengetikkan:

install GD

Panduan lebih lengkap mengenai cara menginstal modul dapat dibaca pada manual perlmodinstall .

Memakai Modul GD di Perl

Mari kita lihat program kecil ini:

use GD;
$im = new GD::Image(100,100);
$white = $im->colorAllocate(255,255,255);
$blue = $im->colorAllocate(0,0,255);
$black = $im->colorAllocate(0,0,0);
$im->rectangle(0,0,99,99,$black);
$im->arc(50,50,95,75,0,360,$blue);
$im->string(gdSmallFont,20,40,"Perl is Cool",$blue);
binmode STDOUT;
print $im->png;

Program ini memakai library GD, jadi ada use GD; di awal program. Lalu program akan memanggil metode new, untuk membuat image baru berukuran 100 x 100 piksel. Tiga buah warna akan dialokasikan, dengan memanggil metode colorAllocate. Sebuah border berwarna hitam digambar, kemudian sebuah lingkaran berwarna biru dibuat, lalu string “Perl is Cool” berwarna biru dituliskan dalam font kecil.

Perlu Anda perhatikan bahwa sistem koordinat yang dipakai oleh GD adalah koordinat kartersius dengan titik (0,0), ada di kiri atas, sumbu X positif ke arah kanan, dan sumbu Y positif ke arah bawah.

Setelah gambar selesai dibuat, kita perlu mengeset mode STDOUT menjadi mode biner, agar data dapat dicetak dengan benar. Metode png() akan mengembalikan data dalam format PNG. Untuk menjalankan program tersebut, Anda bisa melakukan ini:

perl testpng.pl > test.png

atau jika Anda ingin agar filenya langsung tersimpan dalam format png, tanpa harus diredireksi ke file, ganti dua baris terakhir menjadi:

open(F, ">hello.png");
binmode F;
print F $im->png;
close(F);

Salah satu contoh implementasi penggunaan library ini adalah untuk pembuatan grafik log. Di edisi yang lalu Anda sudah dapat memparse dan membuat laporan dari sebuah file log, sekarang Anda dapat berlatih untuk menciptakan visualisasi log tersebut sehingga lebih menarik untuk dilihat.

Penutup

Dalam edisi ini Anda sudah belajar mengenai referensi dan penggunaannya untuk pemanggilan subrutin dengan melewatkan parameter sebagai referensi (pass by reference). Anda juga sudah belajar bagaimana membuat modul sederhana. Dengan berbekal dua hal tersebut, semakin banyak yang dapat Anda lakukan dengan Perl.

Dalam edisi ini juga telah dibahas dasar-dasar pemrograman OO di Perl. Dasar-dasar tersebut cukup untuk mengerti bagaimana memanfaatkan modul OO yang sudah sangat banyak. Di edisi-edisi yang akan datang, pembahasan referensi, package, dan modul yang lebih dalam akan terus dilakukan, dengan memberikan banyak contoh implementasi di dunia nyata.

Yohanes Nugroho mahasiswa S1 IF ITB yang baru-baru ini menempuh sidang akhirnya. Administrator Jaringan Teknik Informatika. Asisten di Teknik Informatika. Programmer Satgas Pengolah Data Institut ITB. Dapat dihubungi di yohanes@opensource.or.id.

mw

Arsip mwmag[Files]  [Up]www.master.web.id/mwmag