Percabangan if, elsif, else, dan unless

Percabangan if, elsif, dan else beserta kebalikannya unless, termasuk modifier pernyataan berbentuk X if Y.

Daftar isi

Program tidak selalu berjalan dari baris pertama sampai baris terakhir. Pada banyak titik, program perlu memilih tindakan yang berbeda sesuai nilai yang sedang dipegangnya, misalnya menetapkan predikat sebuah skor ujian atau menandai peserta yang absen. Topik ini membahas percabangan pada Perl, yaitu pernyataan if dengan rantai elsif dan else, pernyataan unless sebagai kebalikannya, serta modifier pernyataan berbentuk X if Y. Pembahasan diawali aturan nilai kebenaran Perl karena seluruh percabangan bertumpu pada aturan tersebut. Setelah topik ini dipahami, percabangan dapat ditulis dengan struktur yang benar sekaligus gaya yang khas Perl.

Nilai kebenaran dalam Perl#

Perl tidak memiliki tipe data boolean. Setiap ekspresi dapat dinilai benar atau salah, dan yang dianggap salah hanyalah empat nilai, yaitu angka 0, string "0", string kosong "", dan undef. Seluruh nilai lainnya dianggap benar, termasuk string "0.0", string yang hanya berisi spasi, dan angka negatif. Aturan ini menjelaskan mengapa kondisi if pada Perl tidak selalu memerlukan operator perbandingan, karena nilai apa pun sudah dapat dinilai langsung.

Skrip berikut menguji sembilan nilai kandidat dan melaporkan penilaiannya. Setiap elemen array @uji berupa pasangan berisi label dan nilai yang dinilai, sehingga kasus undef dapat dilaporkan tanpa memicu peringatan nilai yang belum diinisialisasi. Jalankan skrip dengan perintah perl nilai-kebenaran.pl dari direktori tempat berkasnya berada.

perl nilai-kebenaran.pl
use strict;
use warnings;

my @uji = (
    [ '0',       0 ],
    [ '"0"',    '0' ],
    [ '""',      '' ],
    [ 'undef', undef ],
    [ '0.0',   0.0 ],
    [ '"0.0"', '0.0' ],
    [ '" "',    ' ' ],
    [ '-1',      -1 ],
    [ '"Nol"', 'Nol' ],
);

foreach my $pasangan (@uji) {
    my ($label, $nilai) = @$pasangan;
    if ($nilai) {
        print "$label bernilai benar\n";
    }
    else {
        print "$label bernilai salah\n";
    }
}
text Keluaran
0 bernilai salah
"0" bernilai salah
"" bernilai salah
undef bernilai salah
0.0 bernilai salah
"0.0" bernilai benar
" " bernilai benar
-1 bernilai benar
"Nol" bernilai benar

Hasil di atas menegaskan dua kasus yang sering mengejutkan pemula. Nilai 0.0 dinilai salah karena nol tetap nol, berapa pun cara penulisannya. Sebaliknya, string "0.0" dinilai benar karena isinya bukan "0" dan tidak kosong. Ketelitian pada kasus ini penting apabila kondisi berisi data dari luar program, misalnya masukan pengguna yang selalu berupa string.

Struktur if, elsif, dan else#

Pernyataan if mengeksekusi bloknya apabila kondisinya dinilai benar. Kondisi ditulis tanpa tanda kurung, sedangkan blok yang mengapit pernyataannya ditulis dengan kurung kurawal dan tidak boleh dihilangkan, bahkan apabila isinya hanya satu baris. Aturan kedua ini membedakan Perl dari bahasa turunan C yang mengizinkan percabangan tanpa kurung kurawal.

Bentuk lengkapnya memuat satu kondisi if, nol atau lebih kondisi elsif, dan satu blok else yang bersifat opsional, sebagaimana bentuk umum berikut.

perl Bentuk umum if, elsif, dan else
# tidak-dijalankan
if (KONDISI_1) {
    PERNYATAAN
}
elsif (KONDISI_2) {
    PERNYATAAN
}
else {
    PERNYATAAN
}

Kondisi elsif dievaluasi hanya apabila seluruh kondisi sebelumnya salah, dan eksekusi berhenti pada kondisi pertama yang benar, sehingga urutan penulisan kondisi menentukan hasilnya. Blok else menampung seluruh kasus yang tidak tertangkap oleh kondisi di atasnya. Skrip berikut menetapkan predikat untuk lima skor ujian dan menunjukkan peran urutan kondisi tersebut.

perl penilaian.pl
use strict;
use warnings;

my @skor = (95, 81, 68, 52, 40);

foreach my $skor (@skor) {
    my $predikat;

    if ($skor >= 90) {
        $predikat = 'A';
    }
    elsif ($skor >= 80) {
        $predikat = 'B';
    }
    elsif ($skor >= 70) {
        $predikat = 'C';
    }
    elsif ($skor >= 60) {
        $predikat = 'D';
    }
    else {
        $predikat = 'E';
    }

    print "Skor $skor memperoleh predikat $predikat\n";
}
text Keluaran
Skor 95 memperoleh predikat A
Skor 81 memperoleh predikat B
Skor 68 memperoleh predikat D
Skor 52 memperoleh predikat E
Skor 40 memperoleh predikat E

Skor 68 memperoleh predikat D meskipun nilainya juga kurang dari 80 dan kurang dari 90, karena kondisi $skor >= 60 merupakan kondisi pertama yang benar. Apabila urutan kondisinya dibalik, sebagian skor terklasifikasi keliru karena kondisi yang lebih longgar tertangkap lebih dahulu. Kaidah yang perlu dipegang adalah menulis kondisi dari yang paling ketat ke yang paling longgar.

Percabangan unless#

Pernyataan unless adalah kebalikan dari if. Bloknya dieksekusi apabila kondisinya dinilai salah dan dilewati apabila kondisinya benar, sehingga unless ($x == 0) setara dengan if ($x != 0). Bentuk ini dipilih apabila kondisi positif justru membingungkan ketika dibalik, misalnya pemeriksaan bahwa sebuah nama tidak kosong. Karena sifatnya itu, unless sering muncul pada pemeriksaan prasyarat, misalnya memastikan sebuah nilai sudah terisi sebelum diproses.

Negasi juga dapat dinyatakan dengan operator ! yang membalik nilai kebenaran, sehingga if (!$aktif) dan unless ($aktif) berperilaku sama. Pilihan di antara keduanya merupakan perkara keterbacaan, bukan perilaku. Kaidah yang lazim membatasi unless pada kondisi sederhana yang berisi satu pemeriksaan, sedangkan kondisi majemuk lebih mudah diurai apabila ditulis dengan if beserta negasinya. Perl menyediakan bentuk unless dengan blok else, tetapi gaya penulisan modern menyarankan if untuk percabangan yang memiliki dua cabang.

Skrip berikut menyapa seluruh peserta kecuali yang tercatat absen. Pernyataan unless ($nama eq $absen) terbaca sebagai jalankan blok ini apabila nama bukan peserta absen, yang lebih langsung daripada bentuk negasinya.

perl sambutan.pl
use strict;
use warnings;

my @peserta = ('Dewi', 'Budi', 'Citra');
my $absen = 'Budi';

foreach my $nama (@peserta) {
    unless ($nama eq $absen) {
        print "$nama hadir pada pertemuan ini\n";
    }
}
text Keluaran
Dewi hadir pada pertemuan ini
Citra hadir pada pertemuan ini

Keluarannya memuat dua nama karena satu-satunya peserta absen dilewati tanpa pesan apa pun. Bentuk negasi yang setara untuk kasus ini adalah if ($nama ne $absen), dengan operator perbandingan string ne dan bukan != yang berlaku untuk angka. Operator ne menghasilkan nilai benar apabila kedua stringnya berbeda, sehingga kondisi tersebut benar untuk setiap nama selain peserta yang absen.

Modifier pernyataan#

Perl menyediakan cara ringkas untuk menempatkan satu pernyataan bersyarat pada satu baris, yaitu modifier pernyataan (statement modifier). Bentuknya adalah X if Y, yang berarti X dijalankan apabila Y benar, serta X unless Y, yang berarti X dijalankan apabila Y salah. Konstruksi ini terbaca seperti kalimat berbahasa Inggris dan menjadi salah satu gaya khas Perl.

perl Bentuk umum modifier pernyataan
# tidak-dijalankan
PERNYATAAN if KONDISI;
PERNYATAAN unless KONDISI;

Modifier pernyataan hanya menerima satu pernyataan tanpa blok dan tanpa kurung kurawal, sehingga bentuk ini tepat untuk tindakan tunggal yang pendek. Apabila tindakannya memerlukan beberapa baris, tulis kembali dalam bentuk if biasa beserta bloknya. Penempatan kondisi di belakang juga mengubah penekanan pembacaan, karena tindakan dibaca lebih dahulu daripada syaratnya.

Skrip berikut mengelompokkan kata berdasarkan panjangnya dengan dua modifier sekaligus, satu berbentuk X if Y dan satu berbentuk X unless Y. Fungsi length($kata) menghitung jumlah karakter pada sebuah string.

perl panjang-kata.pl
use strict;
use warnings;

my @kata = ('menulis', 'dan', 'mengirim', 'arsip');

foreach my $kata (@kata) {
    print "$kata termasuk kata panjang\n" if length($kata) > 4;
    print "$kata termasuk kata pendek\n" unless length($kata) > 4;
}
text Keluaran
menulis termasuk kata panjang
dan termasuk kata pendek
mengirim termasuk kata panjang
arsip termasuk kata panjang

Kesalahan umum#

Kesalahan pertama adalah menulis operator penugasan = di dalam kondisi padahal yang dimaksud adalah perbandingan ==. Pernyataan if ($skor = 100) menyimpan angka 100 ke $skor, lalu menilai kondisinya benar karena 100 bukan salah satu dari empat nilai yang dianggap salah, sehingga bloknya selalu tereksekusi dan nilai $skor ikut berubah. Perl membantu melalui peringatan Found = in conditional, dan perbaikannya adalah menggunakan == untuk angka serta eq untuk string.

Kesalahan kedua adalah menghilangkan kurung kurawal pada blok percabangan. Baris seperti if ($aktif) print "aktif"; tidak sah pada Perl dan memicu error sintaks, karena blok kurung kurawal merupakan bagian wajib struktur percabangan. Perbaikannya adalah mengapit pernyataan dengan kurung kurawal atau memindahkan tindakan tunggal tersebut ke bentuk modifier pernyataan.

Kesalahan ketiga adalah mengeja kata kunci elsif menjadi elseif atau elif, kebiasaan yang terbawa dari bahasa pemrograman lain. Perl tidak mengenal kata kunci tersebut dan melaporkan error sintaks pada baris yang bersangkutan. Perbaikannya adalah mengikuti ejaan resmi Perl, dan pesan error dari perl biasanya sudah menunjuk kata yang tidak dikenal itu.

Ringkasan#

  • Perl menilai kebenaran tanpa tipe boolean. Nilai yang dianggap salah hanyalah 0, "0", "", dan undef, sedangkan nilai lainnya benar.
  • Percabangan if wajib menggunakan blok kurung kurawal, dapat menerima rantai elsif yang dievaluasi berurutan, dan dapat ditutup dengan blok else opsional. Kebalikannya adalah unless.
  • Modifier pernyataan berbentuk X if Y dan X unless Y merangkum satu pernyataan bersyarat pada satu baris tanpa blok.
  • Operator perbandingan angka adalah == dan perbandingan string adalah eq. Penugasan = di dalam kondisi merupakan sumber error yang dilaporkan use warnings.

Referensi#