Belajar Ruby Dari Agan Magico


Iseng buka Kaskus ada Info menarik dan patut untuk dipelajari dari agan Magico, Bagi yang belum mengerti Ruby pasti Berpikir kalo ruby itu SUSAH.. Ya okelah.. Makanya belajar, berikut penjelasan agan 
MAGICO 

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Berhubung Java ane mentok, ane refreshing dulu de bikin thread ruby disini..
Ruby itu adalah language yang pure Object Oriented. Tidak ada primitives di Ruby. Dari mulai definisi sampai operator seluruhnya adalah object.
Ruby adalah strong typed language. Artinya Ruby memiliki tipe data yang baku. Contoh:


Code:
a = "test" #-> string
a = 123 #-> berubah integer
a = (1..4) #-> berubah range
a = a.to_a #->berubah array
Masing masing memiliki method sendiri sendiri.

Kemudian Ruby adalah convention over configuration. Artinya Ruby mengutamakan konvensi penulisan. Misalnya dalam penulisan variable:
Code:
$global #-> global variable
@instance #-> instance variable
@@class #-> class variable
lokal #-> local variable
CONSTANT # -> Constants
Class #-> Constant names
:symbol #-> symbol
Class variable bisa diakses classwide beserta seluruh instance instancenya. Misalnya kita memiliki 3 instances, dan kita memiliki sebuah variable @@counter pada class, maka ketiga instances itu bisa mengakses variable @@counter yang sama.

Kemudian untuk data type, ruby mengenal beberapa data type basic dibawah ini:
Code:
a="1"
a.class #-> String
a.to_i
a #-> 1
a.class #-> Fixnum
/[,\[\]]/.class #-> Regexp
123.45.class #-> Float
:sym.class #-> Symbol
(1..4) #-> range
[1..4] #-> array
{:kaskus => "www.kaskus.us", :google => "www.google.com"} #-> Hash
a=<
Daftar Makanan
1. Es Krim
2. Donat
3. Nasi goreng
MAKANAN
a #-> "Daftar Makanan\n1. Es Krim\n2. Donat\n3. Nasi goreng\n
a.class #-> String
Seluruhnya adalah object pada Ruby. Jadi kita bisa melihat turunan dari apa data type tersebut dengan menggunakan class method. Jadi Ruby mengenal data type berupa String, Fixnum (Integer, tetapi pada 64 bit Linux menjadi Long), Bignum, Float, Symbol, range, array, Hash, dan RegExp.

Selain itu, apapun yang kita berikan pada Ruby, akan selalu dianggap sebagai instance baru. Contoh berikut, akan memberikan 2 buah String instances
Code:
irb> "hastalavista beibeh".object_id
32564740
irb> "hastalavista beibeh".object_id
32577260
Control Structures
Ada beberapa control structure, yang cukup standard yang dimiliki Ruby:
Yang pertama adalah if-elsif-else dan unless
Code:
a=5
if a==4 then b="ok" else b="no" end
unless adalah negation dari if
Code:
unless a==4
b="no"
end
Tidak ada else untuk unless

Cara penulisan tersebut bisa juga dirubah menjadi
Code:
b="ok" if a==4
atau
Code:
b="no" unless a==4
Selain itu juga ada short-if expression seperti biasa yaitu
Code:
b=(a==4 ? "ok" : "no")
Berikutnya adalah case
Code:
case
when a < 5 then "fail"
when a == 5 then "barely pass"
when a > 5 then "pass"
end
Atau cara kedua adalah
Code:
case a
when 0..4 then "fail"
when 5 then "barely pass"
when 6..7 then "ok"
when 8..9 then "good"
when 10 then "perfect!"
else "huh?"
end
Seperti ane bilang, Ruby adalah pure OO, maka case disini juga adalah object yang berarti passable. Contoh
Code:
result = case a
when 0..4 then "fail"
when 5 then "barely pass"
when 6..7 then "ok"
when 8..9 then "good"
when 10 then "perfect!"
else "huh?"
end
atau dikirim ke method
Code:
puts case a
when 0..4 then "fail"
when 5 then "barely pass"
when 6..7 then "ok"
when 8..9 then "good"
when 10 then "perfect!"
else "huh?"
end
Berikutnya adalah while dan until
Code:
while a<10
a++
end
until a>=10
a++
end
cara tersebut juga bisa ditulis
Code:
a++ while a<10
a++ until a>=10
Lanjutan control structure, masih berupa loop
Oh.. satu lagi.. ane lupa.. pada while, until, bisa dilakukan block pada statement tersebut misalnya
Code:
a++ until a>=10
bisa juga menjadi
Code:
begin
a++
end until a>=10
Kemudian ada juga for loop.. syntaxnya adalah for .. in ..
Code:
for a in (0..5) 
puts a
end
Cara ini tetap menggunakan class Fixnum, tetapi cara yang lebih ane sukai adalah menggunakan method times pada Fixnum.
Code:
5.times do |i| puts i end
atau bisa juga pengganti dari do adalah
Code:
5.times { |i|
puts i
}
Kalau pada array, bisa juga digunakan method each
Code:
a=%w(juragan bakso)
a.each { |i|
puts "ini #{i}"
}
hasilnya adalah
Code:
ini juragan
ini bakso
Pada loop, juga tersedia control keyword break, next, redo dan retry. break berfungsi untuk menghentikan inner most loop, dan next berfungsi untuk melanjutkan loop pada value berikutnya. Sedangkan redo untuk mengulang sebuah loop tersebut. Contoh
Code:
m=false
10.times { |i|
next if i < 3
break if i > 8
puts "ini #{i}"
unless m || i != 6
m=true
redo
end
}
hasilnya adalah:
Code:
ini 3
ini 4
ini 5
ini 6
ini 6
ini 7
ini 8
Perhatikan pada "ini 6" diulang 2 kali karena ane menyuruh dia untuk redo.
Berhati hatilah dengan redo, karena salah logic bisa menyebabkan infinite loop.

kemudian retry berfungsi untuk mengulang struktur tersebut. Bisa dilakukan pada loop, tetapi biasa berguna dalam exception trapping. Contoh
Code:
a=0
b=5.0
begin
c=b/a
rescue error1
puts "ERROR1"
rescue error2
puts "ERROR2"
rescue ZeroDivisionError
a=2
retry
ensure
puts c
end
Maka kalau terjadi error1 dan error2, kontrol akan pindah ke rescue, melakukan puts "ERROR1" atau puts "ERROR2", dan akan mengeksekusi "puts c". Tetapi bila terjadi ZeroDivisionError, maka program akan merubah angka a menjadi 2 dan mencoba kembali melakukan c=b/a.

EDIT1: Tambahin Control Blocks
EDIT2: Kelupaan Regexp data type
Notasi
Ruby memiliki notasi yang cukup standard, seperti

Code:
0x0F #->hex
0b0000001 #->binary
0544 #-> octal
?a #-> character code dari "a"
Kemudian backlash notation yang bisa dipakai dalam string
Code:
\n
\r
\f # ->form feed
\b # -> backspace
\a # -> bell
\e # -> escape
\s # ->space
\nnn # -> Octal notation
\xnn # -> Hex notation
\cx. #C-x -> Ctrl-x
\x # #-> karakter x
Kemudian ada beberapa aturan yang harus dipenuhi methods. yaitu ? dan !
Contoh pada method:
Code:
authenticated?(uid, pwd)
Itu berarti return result adalah boolean. True and false. Contoh yang biasa sering dipakai adalah anonymous method defined?
Code:
defined? super #-> apakah bisa memanggil super?
defined? a #-> apakah variable a telah didefinisikan?
defined? puts #-> "method" exists.
defined? berguna sekali untuk melihat apakah object tersebut ada dan berfungsi. Dan karena Ruby adalah pure Object Oriented Language, object dalam hal ini, berarti method, class, module, variable, includes, gems, library, bahkan operator

Code:
to_a!
Bila ada tanda seru di belakang, method tersebut harus digunakan secara berhati hati, karena method ini akan merubah object tersebut secara permanen.

Operators

Arithmetic
Untuk perhitungan, operator cukup standard, yaitu +, -, *, /, % dan exponential adalah ** (bukan ^), demikian pula dengan assignment seperti *=, +=, dst.

Comparison
Yang cukup standard adalah ==, <=, =>, > dan <. Kemudian Ruby memiliki beberapa operator tambahan, yaitu:
<=> - Ini adalah combined operator. Hasilnya adalah 0 bila kedua operand sama, 1 bila yang dikiri lebih besar, dan -1 bila yang dikanan lebih besar.
=== - Ini adalah membership. Misalnya (1..10) === 5 akan menghasilkan true karena 5 adalah member dari 1 hingga 10

kemudian ada 2 buah comparison method, yaitu:
.eql? yang membandingkan tipe dan value.
.equal? yang membandingkan object_id.

Parallel Assignment
Contoh kita akan mengisi 3 buah variable:
Code:
a=1
b=2
c=3
Kita bisa melakukan parallel assignment seperti berikut:
Code:
a,b,c = 1,2,3
Hal ini berguna bila kita ingin menukar isi variable misalnya
Code:
a,b = b,c
Lanjuuttt.. mumpung ane lupa bawa bahan bahan dari rumah ke kantor.
Sekarang mengenai manipulasi variable basic
String
String memiliki kemampuan object parsing, seperti PHP. Jadi kita bisa memberikan beberapa expression dalam string. Contoh:
Code:
x,y,z = 10,20,30
puts "x value adalah #{x}"
puts "x + Y = #{x + y}"
puts "rata rata xyz adalah #{(x+y+z)+3}"
Cara lain untuk menunjukkan string adalah:
Code:
%Q{ Test Test #{x} } # ->" Test Test 10 "
%q{ Test Test #{x} } # " Test Test #{x} "
Kemudian ada satu variable global untuk menentukan encoding dari string, yaitu $KCODE. dimana:
Code:
u -> UTF-8
n -> ASCII
e -> EUC
a -> ASCII
Contoh
Code:
$KCODE = 'u'
Untuk merubah menjadi UTF-8

Operasional pada String, lengkapnya bisa dilihat disini
http://ruby-doc.org/core/classes/String.html
Tetapi ada beberapa operasi yang mungkin bakal sering dipake
Operator:
Code:
"%05d" % 123 # "00123"
s="Ha " * 3 # Ha Ha Ha
s << "! # Ha Ha Ha!
Object manipulation
Code:
"juragan".casecmp("JURAGAN") # 0
"juragan"[3..6] # "agan"
"juragan bakso".each(' ') { } # jadi 2 array, juragan dan bakso
"string\nline".each_line { } #line array
"string".each_char { }
search & replace
Code:
a = "hello there"
a[/[aeiou](.)\1/] #=> "ell"
a[/[aeiou](.)\1/, 0] #=> "ell"
a[/[aeiou](.)\1/, 1] #=> "l"
a[/[aeiou](.)\1/, 2] #=> nil
a["ell"] # => 'ell' (search for ell)
a["bye"] # => nil (search for bye)
"hello".gsub(/[aeiou]/, '*') #=> "h*ll*"
"abcd".insert(0, 'X') #=> "Xabcd"
a.scan(/(..)(..)/) #=> [["he", "ll"], ["o ", "th"], ["er", "e"]]
Arrays
Ada beberapa cara untuk membentuk array
Code:
arr = []
arr = Array.new(20)
arr = Array.new(4,"bla") # -> ['bla','bla','bla','bla']
Kita juga bisa memanfaatkan looping object untuk mengisi array
Code:
arr = Array.new(5) { |i| i = i * 2 } # => [0, 2, 4, 6, 8]
Beberapa operasi pada array diantaranya adalah
Code:
arr1 = [1,2,3]
arr2 = [3,4,5]
arr1 << 4 # => [1,2,3,4]
arr1 & arr2 # => 3
arr1 * 2 # > [1, 2, 3, 1, 2, 3]
arr1 + arr2 # => [1, 2, 3, 3, 4, 5]
arr1 - arr2 # => [1, 2]
arr1 | arr2 # => [1, 2, 3, 4, 5]
arr1.delete(2) #=> [1, 3]
arr1.delete_at(2) # [1, 2]
arr1.delete_if {|i| .... } # delete kalau block mengeluarkan hasil true
arr1.length # => 3
Kemudian yang sering juga dipakai di Ruby adalah hash. Operasional hash sama dengan array, bedanya hash memiliki label pada setiap element sebagai pengganti index.

Class
Definisi class di Ruby adalah:

Code:
class Customer
end
Perhatikan, bahwa Customer menggunakan huruf besar, karena class adalah constant object. Dengan demikian, berarti bahwa Customer adalah constant object.
Tidak dibutuhkan constructor di Ruby, tetapi bila mau kita bisa menambahkan
Code:
class Customer
@@customer_no = 0
def initialize(id, name)
@cust_id=id
@cust_name=name
@@customer_no++
end
end
Maka kita bisa membuat instance dengan menggunakan
Code:
customer = Customer.new('m1', 'magico')
Method
Ingat, customer adalah instance object, dan Customer adalah constant object, terlihat dari huruf besar dan kecil yang mendefinisikannya. Karena itu method, selalu didefinisikan dengan huruf kecil. Contoh:
Code:
class Customer
def beli(itemid)
@item=Item.new(itemid)
end
def self.beli(itemid)
return Item.new(itemid)
end
end
Perhatikan 2 macam penulisan diatas.
self adalah apa yang disebut sebagai static pada bahasa lain. Untuk memanggil self, digunakan
Code:
Customer::beli('m45-355s')
Customer.beli('m45-355s')
sedangkan untuk memanggil beli digunakan
Code:
s = Customer.new
s.beli('m45-355s')
Pada kasus pertama, Customer akan mengembalikan data item dengan kode barang 'm45-355s' ke caller. Sedangkan pada kasus kedua, item tersebut akan diattach juga ke file customer.

Kalau masih ingat mengenai variable scope diatas, kita bisa membuat @@item sehingga item yang dibeli oleh customer tersebut ter-update untuk seluruh instance. Contoh:
Code:
class Customer
@@test1=0
@test2=0
def add
@@test1++
@test2++
end
def print
puts "#{@@test1}/#{@test2}"
end
end

a=Customer.new
b=Customer.new
a.add
b.add
a.print # -> 2/1
b.print # -> 2/1
a.add
a.print # -> 3/2
b.print # -> 3/1
Untuk assign default value, kita gunakan
Code:
def method(var1=value1, var2=value2)
end
Setiap method dalam Ruby akan selalu mengembalikan value. Bila tidak ada return, maka value terakhir yang dideclare akan dikembalikan ke caller
Code:
def test
a=1
b=2
c=3
end
a=test #-> 3
Ingat, a adalah lokal variable, dengan scope lokal.

Sedangkan return memiliki kemampuan untuk mengembalikan beberapa value sekaligus. Contoh:
Code:
def test
return 1,2,3
end
s=test # -> [1,2,3] dalam bentuk array
Kemudian untuk variable parameter, bisa dideklarasikan dengan
Code:
def test (*a)
puts "jumlah parameter #{a.length}"
a.length.times{ |i|
puts "parameter ke #{i} adalah #{a[i]}"
}
end
Satu hal lagi yang unik dari Ruby, adalah method destructor. yaitu undef
Code:
def test (*a)
puts "jumlah parameter #{a.length}"
a.length.times{ |i|
puts "parameter ke #{i} adalah #{a[i]}"
}
end
undef test
Dengan ini kita bisa menghapus sebuah method dari sebuah class.

Overloading, inheritance, singleton
untuk overload method, atau menambahkan method, kita cukup melakukan
Code:
class Test
def overloaded
100
end
def original
10
end
end
Kita bisa mendefinisikan class lagi
Code:
class Test2 < Test
def overloaded
super
200
end
def newmethod
20
end
end
Sedangkan singleton didefinisikan dengan amat sangat mudah, yaitu dengan:
Code:
test1=Test2.new
test2=Test2.new
def test2.newmethod
30
end
test2.newmethod # -> 30
test1.newmethod # -> 20

Modules
Sekarang mengenai "class" kedua yang dimiliki Ruby, yaitu class yang tidak bisa di-inherit. Class ini disebut module. Dalam Ruby, ini disebut mixin. Bisa juga untuk mendefinisikan namespace.
Contoh:

customer.rb
Code:
module Customer
DEALER=25
USER=0
def self.discount(type)
return type
end
end
barang.rb
Code:
module Barang
PPN = 10
def self.pajak(jenis)
return jenis
end
end
Untuk menggunakan ini, kita bisa melakukan
Code:
require 'customer'
Customer::DEALER
Customer.discount(CUSTOMER::USER)
Atau bisa juga di-embed ke dalam class
Code:
require 'customer'
class Customers
include Barang
def hitung
return Barang.pajak(Barang::PPN)
end
end
c = Customers.new

c.pajak
c.hitung
Dengan demikian, maka class Customers akan memiliki seluruh method dari module Barang

Bisa juga kita menambahkan
Code:
class Customers
include Barang
include Customer
def hitung
end
end
Maka instance dari Customers akan inherit Barang, Customer, dan Customers sekaligus.
Dengan cara ini, kita bisa membuat method method yang common digunakan pada beberapa class, dan me-mixin ke dalam class class tersebut.

Attributes
Pada bahasa yang lain, kita biasa menggunakan
Code:
private String attribute;
function getAttribute() {}
function setAttribute(String attr) {}
Pada Ruby, dikenal statement
Code:
@attribute = ""
def attribute
return @attribute
end
def attribute=(a)
@attribute = a
end
Itu adalah cara sulit, tetapi mengijinkan kita untuk melakukan override. Tetapi kebanyakan attribute hanya get dan set polos. Pada Ruby, kita bisa menggunakan attr
Code:
attr_accessor :attribute1, :attribute2 # -> get/set
attr_reader :attribute # -> get only
attr_writer :attribute # -> set only.
Advanced Class
Di dalam Ruby, class adalah instance dari object Class. Perhatikan tanda "C" huruf besar, dan deklarasi class dengan "c" huruf kecil. Pada Ruby, class Customer berarti kita memanggil method class dengan parameter Customer. Karena itu, dalam Ruby setiap Class object memiliki beberapa Class method dan properties, yang akan di-inherit oleh setiap class yang didefinisikan. Beberapa diantaranya adalah to_s, method_missing, to_i, dst, yang otomatis akan ada pada instance walaupun kita tidak mendefinisikannya. Karena itu, bila kita tidak mendefinisikan class tersebut inherit dari class lain, maka default Ruby adalah
Code:
class ClassName < Class
end
Untuk melihat method dalam sebuah class, bisa digunakan
Code:
Class.instance_methods
Class.private_methods
Class.methods
Setiap method yang agan lihat disana, bisa di-override, untuk membuat jenis "class" yang baru. Berhati hatilah, karena itu adalah inner working dari Ruby. Contoh adalah method_defined? yang tersedia untuk instances, dan method_missing yang adalah private method. Bila method_defined? memberikan false, dan kita memanggil method itu, maka akan dipanggil method "method_missing". Untuk ini, kita bisa overload method_missing ini untuk lebih "berguna". Misalnya membaca nama method yang diminta oleh caller, dan merubahnya sehingga dikenali oleh class tsb. Agan bisa lihat ada method bernama "initialize" yang berfungsi sebagai constructor, kemudian catch, throw, clone, singleton_class, private_method, dan beberapa operator seperti ===, ==, <=>, dst. Kalau agan ingin mengubah cara kerja Class object, agan bisa melakukannya dalam class yang agan buat.

Yang biasa di-overload adalah:
Code:
to_s
method_missing
dan umumnya, programmer melakukan send untuk mengirim message kembali ke class tersebut.
Code:
send "method", "parameters"
Agan juga bisa overload atau extend Class object dengan melakukan
Code:
class Class  
def test
end
end
Maka method test akan inherited pada class yang agan buat. method (def) adalah berupa Module, dan merupakan mixin dari Class.
Tapi peringatan dari ane, kalau melakukan ini, BE CAREFUL.

0 comments:

Post a Comment

Popular Posts