Cara kerja Ruby

Ruby sebagai bahasa interpretatif, model segala-sesuatu-adalah-objek, dan eksplorasi kode lewat IRB.

Daftar isi

Ruby menjalankan program dengan membaca kode sumber secara langsung, tanpa tahap kompilasi terpisah seperti pada bahasa C. Topik ini menjelaskan alur yang ditempuh kode Ruby dari berkas sumber hingga keluaran, prinsip segala-sesuatu-adalah-objek yang menjadi fondasi bahasanya, serta penggunaan IRB untuk mengamati perilaku kode. Pemahaman atas ketiganya membuat perilaku program Ruby lebih mudah diprediksi dan pesan error lebih mudah dibaca.

Dari kode sumber hingga keluaran#

Ruby termasuk bahasa interpretatif (interpreted), yaitu bahasa yang kode sumbernya dieksekusi langsung oleh program yang disebut interpreter tanpa tahap kompilasi terpisah. Pada bahasa seperti C, kode sumber harus dikompilasi menjadi berkas biner sebelum dijalankan, sedangkan Ruby cukup menerima nama berkasnya lalu langsung bekerja. Pola kerja ini mempercepat siklus menulis, mengubah, dan menjalankan ulang program.

Di balik kesederhanaannya, terdapat beberapa tahap yang berlangsung cepat setiap kali program dijalankan. Interpreter membaca teks kode sumber, lalu menguraikannya dengan komponen yang disebut parser, yakni bagian yang membaca teks dan menyusun struktur program dari situ. Hasil penguraian diterjemahkan menjadi bytecode, yaitu rangkaian instruksi untuk virtual machine atau mesin virtual, dan instruksi itulah yang benar-benar dieksekusi. Mesin virtual bawaan Ruby bernama YARV, sedangkan parser yang menjadi bawaan sejak Ruby 3.4 bernama Prism.

Alur lengkapnya tampak pada diagram berikut.

Berkas .rbParser PrismBytecodeMesin virtualYARVKeluaran
Alur eksekusi program Ruby

Model ini membawa dua konsekuensi praktis. Kesalahan sintaks baru terdeteksi ketika berkas dijalankan, karena parser bekerja pada saat itu juga. Selain itu, tidak ada langkah build yang harus dilalui, sehingga mengubah satu baris dan menjalankan ulang hanya memerlukan hitungan detik.

Segala sesuatu adalah objek#

Prinsip inti Ruby menyebut segala sesuatu sebagai objek. Artinya, setiap nilai yang dipegang program merupakan wujud dari sebuah kelas, yaitu cetak biru yang mendefinisikan data dan perilakunya. Perilaku tersedia dalam bentuk metode yang dipanggil dengan tanda titik. Berbeda dengan bahasa yang memiliki tipe primitif terpisah untuk bilangan, Ruby memperlakukan bilangan sebagai objek penuh, sehingga metode dapat dipanggil pada nilai yang ditulis langsung sekalipun.

Metode .class melaporkan kelas dari sebuah objek. Berkas berikut memanggil .class pada lima nilai yang berbeda jenis.

ruby objek.rb
# memeriksa kelas milik berbagai nilai Ruby
puts 3.class
puts 3.14.class
puts "halo".class
puts nil.class
puts 3.class.class
text Keluaran
Integer
Float
String
NilClass
Class

Keluaran di atas memperlihatkan rantai yang konsisten. Bilangan bulat 3 adalah instans (instance), yaitu wujud nyata, dari kelas Integer, sedangkan 3.14 berasal dari kelas Float dan teks dari kelas String. Nilai nil, yang menyatakan ketiadaan nilai, ternyata juga objek, yaitu satu-satunya instans kelas NilClass. Baris terakhir adalah bukti yang paling jelas: kelas Integer itu sendiri merupakan objek, dan kelasnya adalah Class. Karena semuanya objek, pertanyaan tentang kelas dan metode dapat diajukan ke hampir semua hal yang muncul di dalam program.

Menguji asumsi lewat IRB#

Ruby menyertakan IRB, singkatan dari Interactive Ruby, yaitu lingkungan interaktif bergaya read-eval-print loop (REPL), siklus yang membaca ekspresi, mengevaluasinya, lalu mencetak hasilnya berulang-ulang. IRB digunakan untuk menguji asumsi kecil tanpa harus membuat berkas. Cara memulainya: ketik irb pada terminal, yaitu jendela tempat perintah diketik dan dijalankan. Setelah sesi terbuka, prompt yang menandai tempat mengetik tampil dalam bentuk seperti irb(main):001>, ekspresi diketik satu per satu, dan hasilnya tampil setelah tanda =>. Perintah exit menutup sesi.

Contoh berikut adalah eksperimen kecil yang layak dicoba pada IRB.

ruby Contoh: eksperimen kecil yang layak dicoba pada IRB
bahasa = "Ruby"
puts bahasa.reverse
puts bahasa.length
text Keluaran
ybuR
4

Apabila dua baris terakhir ditulis pada sesi IRB tanpa puts, IRB menampilkan nilai kembalian setiap ekspresi setelah tanda =>, yaitu => "ybuR" dan => 4. Perbedaan kecil ini penting dipahami: puts mencetak teks ke layar lalu mengembalikan nil, sedangkan ekspresi murni mengembalikan nilainya untuk ditampilkan oleh IRB. Metode reverse membalik urutan huruf, sedangkan metode length menghitung jumlah karakter, dan keduanya adalah contoh metode yang dimiliki setiap string.

Karena umpan baliknya seketika, IRB menjadi tempat yang tepat untuk memverifikasi dugaan sebelum kode ditulis ke berkas program. Kebiasaan ini memangkas waktu pencarian kesalahan karena masalah ditemukan lebih awal.

Kesalahan umum#

Kesalahan yang sering muncul saat mengenal model objek Ruby adalah memperlakukan hasil puts sebagai nilai yang siap diolah. Metode puts mencetak teks ke layar, tetapi nilai kembaliannya adalah nil, sehingga penugasan seperti hasil = puts "mencetak teks" menghasilkan variabel yang berisi nil dan bukan teks yang dicetak. Metode apa pun yang dipanggil pada variabel semacam itu kemudian gagal.

ruby Contoh: hasil puts bukan teks yang siap diolah
hasil = puts "mencetak teks"
begin
  hasil.reverse
rescue NoMethodError => e
  puts e.message
end
text Keluaran
mencetak teks
undefined method 'reverse' for nil

Pesan error pada keluaran menyebut sumber masalahnya secara langsung, yaitu metode reverse dipanggil pada nil, sedangkan nil tidak memiliki metode tersebut. Blok begin/rescue pada contoh digunakan semata untuk menangkap error dan menampilkan pesannya secara ringkas, sebab tanpa penangkapan, interpreter menghentikan program dengan laporan yang jauh lebih panjang. Perbaikannya sederhana: simpan teks ke variabel terlebih dahulu, lalu panggil metode pada variabel tersebut.

ruby Contoh: simpan nilai terlebih dahulu, lalu olah
teks = "mencetak teks"
puts teks.reverse
text Keluaran
sket katecnem

Urutan huruf yang terbalik memang merupakan pekerjaan metode reverse, sehingga keluarannya tampak aneh tetapi benar. Inti perbaikannya ada pada pola tersebut, yaitu menyimpan nilai ke variabel terlebih dahulu, sehingga metode dipanggil pada teks sungguhan dan bukan pada nil. Pola yang sama dapat diuji lebih dahulu pada IRB sebelum digunakan di berkas program.

Ringkasan#

  • Ruby interpretatif: kode sumber diuraikan parser Prism, diterjemahkan menjadi bytecode, lalu dijalankan mesin virtual YARV tanpa tahap kompilasi terpisah.
  • Setiap nilai adalah objek dengan kelas dan metode, termasuk bilangan, string, dan nil yang bertipe NilClass.
  • IRB menyediakan siklus baca-evaluasi-cetak untuk menguji ekspresi, dengan nilai kembalian ditampilkan setelah tanda =>.
  • puts mencetak teks tetapi mengembalikan nil, sehingga nilai yang akan diolah perlu disimpan ke variabel terlebih dahulu.

Referensi#