Menguasai Ruby dalam 20
Menit
Pengantar
Tutorial mini Ruby ini
seharusnya bisa diselesaikan dalam waktu kurang dari 20 menit. Dengan asumsi
Anda sudah menginstal Ruby. (Jika Anda belum menginstal Ruby di komputer Anda, download dan silakan instal Ruby terlebih dahulu
sebelum Anda mengikuti tutorial ini)
irb,
Ruby Interaktif
Buka IRB.
§ Jika
Anda menggunakan Mac OS X buka Terminal dan ketik irb,
kemudian tekan enter.
§ Jika
Anda menggunakan Linux, buka shell
dan ketik irb,
kemudian tekan enter.
§ Jika
Anda menggunakan Windows, buka Interactive
Ruby dari
bagian Ruby di Menu Start Anda.
irb(main):001:0>
Ok, sekarang irb sudah dibuka. Sekarang
mau apa?
Ketik
ini: "Hello
World"
irb(main):001:0> "Hello World"
=> "Hello World"
Ruby
Mematuhi Anda!
Apa yang baru saja terjadi?
Apakah kita baru saja menulis program tersingkat di dunia berupa “Hello World”
? Tidak persis begitu. Baris kedua hanya sekedar cara IRB memberitahu hasil (result)
dari ekspresi terakhir yang dievaluasi/dijalankan. Jika kita ingin print “Hello
World” kita perlu tambahkan sedikit:
irb(main):002:0> puts "Hello World"
Hello World
=> nil
puts merupakan perintah dasar untuk mencetak
(print) sesuatu di Ruby. Tetapi kemudian apa artinya => nil ? Artinya adalah result dari ekspresi.puts selalu return nil, yang merupakan value
absolut ketiadaan di Ruby.
Kalkulator
Gratis Anda Di Sini
Dengan IRB kita sudah cukup
mempunyai kalkulator dasar:
irb(main):003:0> 3+2
=> 5
Tiga
tambah dua. Cukup mudah. Bagaimana dengan tiga kali dua? Anda bisa mencoba dengan langsung
mengetikkannya, cukup pendek, tetapi Anda juga bisa mengganti apa saja yang
baru saja Anda perintahkan di IRB. Coba tekanpanah-atas pada keyboard Anda dan lihatlah apakah
IRB memunculkan baris3+2 lagi. Jika Ya, Anda dapat menggunakan
panah-kiri untuk berpindah ke setelah tanda + kemudian gunakan backspace untuk
menggantinya dengan tanda *.
irb(main):004:0> 3*2
=> 6
Lanjut, mari kita coba tiga kuadrat:
irb(main):005:0> 3**2
=> 9
Di
Ruby, ** merupakan cara Anda mengatakan “kepada
kekuatan dari”. Tetapi bagaimana jika Anda ingin melakukannya dengan cara lain
dan mendapatkan akar dari suatu bilangan?
irb(main):006:0> Math.sqrt(9)
=> 3.0
Ok,
tunggu dulu, bagaimana yang terakhir itu? Jika Anda menebak, “Kode tersebut
mencari sqrt (akar) dari 9”, berarti Anda benar. Tetapi mari kita lihat lebih
dekat. Pertama, apa itu Math ?
Module,
Pengelompokan Kode Menurut Topik
Math merupakan module built-in (bawaan)
untuk matematika. Module punya dua pengaturan di Ruby. Pertama, mengelompokkan
metode-metode yang berfungsi mirip di bawah satu nama yang terkenal. Math juga punya metode-metode seperti sin() dan tan().
Selanjutnya
adalah dot (titik). Apa yang dot lakukan? Dengan dot-lah, Anda bisa
mengidentifikasi receiver dari suatu message. Nah, kalau message apa? Dalam hal
ini, message adalah sqrt(9),
yang artinya pemanggilan metodesqrt,
kependekan dari “square root” dengan parameter 9.
Hasil
dari pemanggilan metode sqrt ini adalah value 3.0.
Anda bisa perhatikan value bukan cuma 3 (tanpa .0).
Itu karena sering angka sqrt tidak akan berupa integer, jadi metode sqrt selalu
return angka floating-point.
Bagaimana jika kita ingin mengingat
hasil dari beberapa perhitungan matematika ini? Caranya assign hasilnya ke
variabel.
irb(main):007:0> a = 3 ** 2
=> 9
irb(main):008:0> b = 4 ** 2
=> 16
irb(main):009:0> Math.sqrt(a+b)
=> 5.0
Sehebat
kalkulator, kita sudah pergi dari message tradisional Hello Worldyang
biasanya selalu saja kalau ada tutorial untuk pemula berfokus disana…jadi
mari kita kembali kesana.
Bagaimana jika kita ingin mengatakan
“Hello” sekaligus banyak tanpa membuat jari dan tangan kita semua kelelahan?
Kita perlu mendefinisikan metode!
irb(main):010:0> def h
irb(main):011:1> puts "Hello World!"
irb(main):012:1> end
=> nil
Kode def h memulai definisi suatu metode. Kode
tersebut berkata pada Ruby bahwa kita sedang mendefinisikan sebuah metode, yang
bernama h.
Baris selanjutnya adalah body (badan) metode, baris yang sama seperti yang
sudah kita lihat sebelumnya: puts
"Hello World". Baris terakhir endmemberitahu
Ruby bahwa kita sudah selesai mendefinisikan metode. Ruby merespon => nil memberitahu kita bahwa Ruby sudah
mengetahui kalau kita sudah selesai mendefinisikan metode h tersebut.
Ringkasan,
Kehidupan Metode yang Berulang-ulang
Sekarang mari kita coba
menjalankan metode tersebut berulang kali:
irb(main):013:0> h
Hello World!
=> nil
irb(main):014:0> h()
Hello World!
=> nil
Nah, mudah khan?! Pemanggilan metode di
Ruby memang semudah menyebut nama metode yang bersangkutan ke Ruby. Jika metode
tidak menerima parameter berarti ya memang itu saja yang Anda butuhkan. Anda
bisa menambahkan buka dan tutup kurung jika Anda suka, tetapi buka dan tutup
kurung tersebut tidak diperlukan.
Bagaimana
kalau kita ingin bilang hello ke orang, dan bukan bilang hello ke seluruh
dunia? Caranya, Anda tinggal mendefinisikan ulang metode h agar menerima name sebagai parameter.
irb(main):015:0> def h(name)
irb(main):016:1> puts "Hello #{name}!"
irb(main):017:1> end
=> nil
irb(main):018:0> h("Matz")
Hello Matz!
=> nil
Sukses… tetapi coba kita lihat dulu
sebentar apa yang terjadi disini.
Variabel
dalam String
Apa
itu tadi artinya #{name} ? Tanda pagar dan kurung kurawal tadi
adalah cara Ruby untuk insert sesuatu ke dalam string. Jadi obyek diantara
kurung kurawal menjadi string (jika belum berbentuk String) kemudian diganti
dengan string di luar kurung kurawal tersebut. Anda juga bisa menggunakan tanda
pagar dan kurung kurawal ini untuk memastikan nama seseorang tersebut telah
diubah menjadi kapital huruf depannya (singkatnya, dikapitalkan, bahasa
Inggrisnya, di-capitalize):
irb(main):019:0> def h(name = "World")
irb(main):020:1> puts "Hello #{name.capitalize}!"
irb(main):021:1> end
=> nil
irb(main):022:0> h "arie"
Hello Arie!
=> nil
irb(main):023:0> h
Hello World!
=> nil
Ada
beberapa trik di metode barusan. Trik pertama, kita panggil metode tanpa
menggunakan buka dan tutup kurung lagi. Jika sudah jelas apa yang Anda lakukan,
maka buka dan tutup kurung boleh dihilangkan (opsional). Trik lainnya adalah
secara default parameter World.
Jadi apa yang metode hkatakan
adalah “Jika name tidak ada, maka gunakan name default yaitu"World"”.
Halo Dunia
Menjadi TukangSapa
Bagaimana jika kita ingin
membuat TukangSapa, jadi satu yang mengingat nama Anda dan menyambut Anda
dengan ucapan selamat datang dan juga yang selalu memperlakukan Anda dengan
hormat. Anda akan membutuhkan obyek untuk keperluan itu. Maka, mari kita buat
kelas “TukangSapa”.
irb(main):024:0> class TukangSapa
irb(main):025:1> def initialize(name = "Dunia")
irb(main):026:2> @name = name
irb(main):027:2> end
irb(main):028:1> def say_hai
irb(main):029:2> puts "Hai #{@name}!"
irb(main):030:2> end
irb(main):031:1> def say_bye
irb(main):032:2> puts "Bye #{@name}, datang lagi ya."
irb(main):033:2> end
irb(main):034:1> end
=> nil
Keyword
baru disini adalah class.
Keyword ini mendifinisikan kelas baru yang disebut TukangSapa dan beberapa
metode untuk kelas TukangSapa tersebut. Juga perhatikan @name.
Ini adalah variabel instan, dan juga tersedia di semua metode di kelas
TukangSapa. Seperti yang bisa Anda lihat variabel instan @name digunakan di metode say_hai dan metode say_bye.
Lalu, bagaimana caranya kita menjalan
kelas TukangSapa ? Membuat
obyek.
Mari kita bikin obyek TukangSapa dan
kita pakai:
irb(main):013:0> t = TukangSapa.new("Arie")
=> #<TukangSapa:0x6b274 @name="Arie">
irb(main):014:0> t.say_hai
Hai Arie!
=> nil
irb(main):015:0> t.say_bye
Bye Arie, datang lagi ya.
=> nil
Sekali
obyek t dibuat, maka obyek t mengingat name adalah Arie. Hmm,
bagaimana jika kita ingin mendapatkan nama saja langsung?
irb(main):017:0> t.@name
SyntaxError: compile error
(irb):17: syntax error, unexpected tIVAR
from (irb):17
from :0
Tidak, caranya tidak bisa begitu.
Di Bawah
Naungan Object yang Sama
Variabel instan tersembunyi
dalam obyek. Variabel instan tidak benar-benar tersembunyi sepenuhnya, Anda
bisa melihat variabel instan kapan saja Anda menginspeksi obyek, dan ada lagi
cara-cara lain untuk mengakses variabel instan, tetapi Ruby menggunakan
pendekatan berorientasi obyek yang bagus untuk menjaga data supaya agak
tersembunyi.
Jadi metode-metode apa yang sebetulnya
ada pada obyek TukangSapa?
irb(main):018:0> TukangSapa.instance_methods
=> ["inspect", "clone", "method", "public_methods",
"instance_variable_defined?", "equal?", "freeze", "methods",
"respond_to?", "dup", "instance_variables", "__id__",
"object_id", "eql?", "id", "singleton_methods",
"send", "taint", "frozen?", "instance_variable_get",
"__send__", "instance_of?", "to_a", "say_hai",
"type", "protected_methods", "instance_eval", "==",
"display", "===", "instance_variable_set", "kind_of?",
"extend", "to_s", "say_bye", "hash", "class",
"tainted?", "=~", "private_methods", "nil?",
"untaint", "is_a?"]
Wih.
Metode-metodenya banyak ya. Padahal kita hanya mendefinisikan dua metode. Apa
yang sebenarnya terjadi? Jadi ini barusan adalah semua metode obyek TukangSapa, list yang
lengkap, termasuk metode-metode yang didefinisikan oleh kelas induk TukangSapa.
Jika kita hanya ingin list metode-metode yang didefinisikan untuk kelas
TukangSapa kita cukup beritahu agar tidak memasukkan induk (ancestor) dengan
melewatkan parameter false,
artinya kita tidak menginginkan metode-metode yang didefinisikan kelas induk
(ancestor).
irb(main):019:0> TukangSapa.instance_methods(false)
=> ["say_bye", "say_hai"]
Nah, begitu. Sekarang coba kita lihat
metode yang mana dari obyek TukangSapa kita yang merespon siapa saja:
irb(main):020:0> t.respond_to?('name')
=> false
irb(main):021:0> t.respond_to?('say_hai')
=> true
irb(main):022:0> t.respond_to?('say_bye')
=> true
irb(main):023:0> t.respond_to?('to_s')
=> true
Hm,
jadi obyek mengetahui metode say_hai,
dan metode to_s (artinya mengkonversi suatu obyek ke
string, metode yang didefinisikan secara default untuk semua obyek), tetapi
obyek tidak mengetahui tentang name.
Mengubah-ubah
Kelas—Tidak Ada yang Pernah Terlalu Terlambat
Tetapi bagaimana jika Anda
ingin bisa melihat atau mengganti name? Ruby menyediakan cara yang mudah untuk
mengakses variabel obyek.
irb(main):024:0> class TukangSapa
irb(main):025:1> attr_accessor :name
irb(main):026:1> end
=> nil
Di
Ruby, Anda dapat membuka kelas lagi dan memodifikasi kelas tersebut.
Perubahan-perubahan tersebut akan hadir pada obyek baru yang Anda buat dan
bahkan tersedia/hadir juga pada obyek yang sudah ada dari kelas yang
bersangkutan. Jadi, coba kita buat satu obyek baru dan bermain dengan property @name.
irb(main):027:0> t = TukangSapa.new('Hendy')
=> #<TukangSapa:0x5b040 @name="Hendy">
irb(main):028:0> t.respond_to?('name')
=> true
irb(main):029:0> t.respond_to?('name=')
=> true
irb(main):030:0> t.say_hai
Hai Hendy!
=> nil
irb(main):031:0> t.name='Yohanes'
=> "Yohanes"
irb(main):032:0> t
=> #<TukangSapa:0x5b040 @name="Yohanes">
irb(main):033:0> t.name
=> "Yohanes"
irb(main):034:0> t.say_hai
Hai Yohanes!
=> nil
Dengan
menggunakan attr_accessor kita sudah mendefinisikan dua metode
baru untuk kita, name untuk mendapatkan (get) value, dan name=untuk
mengatur (set) value.
BosTukangSapa
Menyapa Siapa Saja!
TukangSapa kita sebenarnya
tidaklah terlalu menarik, TukangSapa hanya bisa menyapa satu orang di saat yang
sama. Bagaimana jika kita punya BosTukangSapa yang bisa menyapa dunia (world),
satu orang, atau bahkan seluruh list orang-orang ?
Kali ini, mari kita langsung tulis ke
file saja daripada memakai IRB (Ruby Interaktif).
Untuk keluar dari IRB, ketik “quit”,
“exit” atau tekan saja Control-D.
#!/usr/bin/env ruby
class BosTukangSapa
attr_accessor :names
# Bikin obyek
def initialize(names = "Dunia")
@names = names
end
# Bilang Hai buat semua
def say_hai
if @names.nil?
puts "..."
elsif @names.respond_to?("each")
# @names adalah list, iterate!
@names.each do |name|
puts "Hello #{name}!"
end
else
puts "Hello #{@names}!"
end
end
# Bilang "sampai jumpa" buat semua
def say_bye
if @names.nil?
puts "..."
elsif @names.respond_to?("join")
# Gabung (Join) elemen list dengan koma
puts "Sampai jumpa #{@names.join(", ")}. Datang lagi ya!"
else
puts "Sampai jumpa #{@names}. Datang lagi ya!"
end
end
end
if __FILE__ == $0
mg = BosTukangSapa.new
mg.say_hai
mg.say_bye
# Ganti name menjadi "Azumi"
mg.names = "Azumi"
mg.say_hai
mg.say_bye
# Ganti name menjadi array name
mg.names = ["Steven", "Anton", "Ridho",
"Matz", "Bos"]
mg.say_hai
mg.say_bye
# Change to nil
mg.names = nil
mg.say_hai
mg.say_bye
end
Simpan file dengan nama “ri20min.rb”,
dan jalankan dengan “ruby ri20min.rb”. Outputnya seharusnya menjadi sebagai berikut:
Hello Dunia!
Sampai jumpa Dunia. Datang lagi ya!
Hello Azumi!
Sampai jumpa Azumi. Datang lagi ya!
Hello Steven!
Hello Anton!
Hello Ridho!
Hello Matz!
Hello Bos!
Sampai jumpa Steven, Anton, Ridho, Matz, Bos. Datang lagi ya!
...
...
Menguasai Ruby dalam 20
Menit
Sekarang kita melihat lebih jelas lagi
pada program baru kita, perhatikan baris yang paling pertama, dimulai dengan
tanda pagar (#). Di Ruby, semua tulisan yang ada sesudah tanda pagar (#)
merupakan komentar (comment) dan tidak dipedulikan (di ignore) oleh
interpreter. Baris pertama file adalah hal khusus, dan untuk Sistem Operasi Unix
biasanya kita menentukan bagaimana menjalankan file. Kemudian komentar
selanjutnya untuk penjelasan.
Metode say_hai kita sudah punya trik sedikit:
# Bilang Hai buat semua
def say_hai
if @names.nil?
puts "..."
elsif @names.respond_to?("each")
# @names adalah list, iterate!
@names.each do |name|
puts "Hello #{name}!"
end
else
puts "Hello #{@names}!"
end
end
Sekarang
kelas memperhatikan parameter @names untuk menentukan pilihan. Jika
parameter nil, maka print tiga dot (…). Ya karena memang tidak ada yang perlu
disapa, khan?!
Perulangan—a.k.a.
Iteration
Jika
obyek @names merespon metode each,
berarti obyek ini merupakan sesuatu yang bisa Anda iterate, jadi iterate lah
dan sapalah orang-orang bergantian. Kemudian, jika @names merupakan sesuatu yang lain, biarkanlah
obyek ini otomatis menjadi string dan melakukan sapaan secara default.
Mari kita perhatikan iterator lebih
dalam lagi:
@names.each do |name|
puts "Hello #{name}!"
end
each merupakan metode yang menerima blok
kode yang kemudian menjalankan blok kode tersebut untuk setiap elemen dalam
list, dan diantarado dan end itulah yang dinamakan blok. Blok juga
bisa berupa function anonim atau lambda.
Variabel diantara karakter pipa itu adalah parameter untuk blok tersebut.
Yang
terjadi disini adalah untuk setiap entri dalam list, name terkait dengan elemen list, kemudian
ekspresi puts
"Hello #{name}!" dijalankan
dengan name tersebut.
Kebanyakan
bahasa-bahasa pemrograman lain menangani list dengan menggunakan perulangan for, kalau
di C seperti ini:
for (i=0; i<total_elemen; i++)
{
lakukan_sesuatu_dengan(elemen[i]);
}
Kode
diatas memang jalan, tetapi tidak begitu elegan. Anda perlu variabel i,
untuk mencari tahu berapa panjang/total list, dan juga harus menjelaskan
bagaimana menjalani perulangan lewat list tersebut. Ruby way jauh lebih elegan,
semua detil disembunyikan di metode each,
semua yang perlu Anda lakukan hanyalah memberitahukan apa yang perlu dilakukan
dengan elemen each. Secara internal, metode each akan memanggil yield
"Steven", kemudian yield
"Anton", kemudian yield
"Ridho", dan seterusnya.
Blok,
Kekuatan Ruby
Kekuatan sesungguhnya
tentang blok adalah ketika berhadapan dengan yang lebih rumit ketimbang list.
Selain dari berhubungan dengan list, Anda juga bisa menangani setup, teardown
dan error (yang mana semua itu diluar dari sepengatahuan user)
# Bilang "sampai jumpa" buat semua
def say_bye
if @names.nil?
puts "..."
elsif @names.respond_to?("join")
# Gabung (Join) elemen list dengan koma
puts "Sampai jumpa #{@names.join(", ")}. Datang lagi ya!"
else
puts "Sampai jumpa #{@names}. Datang lagi ya!"
end
end
Metode say_bye tidak menggunakan each,
tetapi memeriksa apakah@names merespon metode join,
jika Ya, maka gunakan join. Tetapi jika tidak, maka print variabel sebagai
string. Metode tidak peduli terhadap typeaktual dari
variabel, hanya bersandar pada metode-metode yang didukung dikenal sebagai
“Duck Typing”, jadi seperti “jalannya seperti bebek dan berbunyi wek wek wek
seperti bebek…”. Keuntungan dari cara duck typing ini adalah kita tidak perlu
membatasi tipe-tipe variabel apa saja yang didukung. Kalau ada orang yang
datang dengan kelas list baru, sepanjang obyek tersebut mengimplementasikan
metode join dengan semantik yang sama seperti list,
maka semua tetap berjalan sama persis seperti yang sudah direncanakan
sebelumnya.
Script
Ruby Mulai!
Begitulah akhir cerita
kelas BosTukangSapa, akhir dari file hanya memanggil metode-metode pada kelas
tersebut. Ada satu trik yang perlu diperhatikan di baris:
if __FILE__ == $0
__FILE__ adalah variabel magic yang berisi nama
file saat ini. $0 adalah nama file yang dipakai ketika
memulai program. Pemeriksaan ini seolah berkata “Jika file ini merupakan file
utama yang digunakan …” Pemeriksaan ini dapat berguna untuk file yang digunakan
sebagai library, jadi bukan untuk mengeksekusi kode, tetapi jika file digunakan
sebagai executable (file yang bisa dieksekusi/execute) maka eksekusi kode
tersebut.
Perdalamlah
Kekuatan Ruby Anda
Demikianlah
tutorial mini Ruby kita. Masih banyak lagi hal-hal yang bisa dijelajahi,
kontrol struktur berbeda yang Ruby tawarkan, penggunaan blok dan yield,
module sebagai mixin, dan banyak lagi yang lain. Saya harap tutorial mini ini
dapat membuat Anda untuk menjelajahi Ruby lebih lanjut.
Jika Anda ingin menjelajahi Ruby lebih
lanjut, silakan ke Dokumentasi yang punya banyak link ke manual dan
tutorial, semua tersedia gratis secara online.
Atau, jika Anda benar-benar ingin buku,
silakan ke daftar buku (link eksternal) (dalam bahasa Inggris)