วันเสาร์, กันยายน 06, 2551

Object ในภาษา ruby

ผมพบว่าการใช้ ruby ในการเรียนรู้เรื่อง OOP เป็นเรื่องที่สนุกทีเดียว ทุกอย่างในภาษานี้เป็น Object ไปหมด แม้แต่ nil ยังเป็น object ด้วย ในตอนแรกผมมุ่งศึกษาตัว Rails เป็นหลัก และพบว่าหากไม่ใช่ Ruby แล้ว Rails คงเกิดได้ยากมาก หากต้องการศึกษา rails ให้มากกว่านี้ผมต้องแม่นเรื่อง Object ของ Ruby ให้มากขึ้น และบทความนี้ผมจะใช้สำหรับเป็น Reference ของตัวเอง ![object](/downloads/object1.png) ทดลองสร้าง Class Circle เพื่อเป็นพิมพ์เขียวให้กับ Object circle #circle.rb class Circle @@count @radious @circle end puts Circle.class_variables #=> @@count puts Circle.instance_variables #=> @circle@radious puts Circle.count #=> undefined method `count' @@count เป็นตัวแปรของ class หรือเรียกว่า class variable ส่วน @radious และ @circle เป็นตัวแปรของ object เมื่อ object ถูกสร้างขึ้น หรือเรียกว่า instance variable ซึ่งจะอธิบายความแตกต่างอีกทีหนึ่ง สังเกตุ error ของบรรทัดสุดท้าย เราจะพบว่า ruby ไม่สามารถอ้างอิงไปที่ตัวแปรโดยตรง แต่จะถามหา method เลย แปลว่าทุกอย่างต้องผ่าน method ที่นี้ลองสร้าง method สำหรับแก้ไขตัวแปร @radious #circle.rb class Circle def radious=(r) @radious = r end def radious return @radious end end circle = Circle.new puts circle.radious #=> nil circle.radious = 4 puts circle.radious #=> 4 เนื่องจาก ruby เป็นภาษาแบบ dynamic การให้โปรแกรมเขียนโปรแกรมจึงเป็นเรื่องปกติมากๆ เช่นในกรณีนี้เราจะมีคำสั่ง attr_reader :radious ใช้เขียนคำสั่ง def radious ... attr_writer :radious ใช้เขียนคำสั่ง def radious=(r) ... attr_accessor :radious ใช้คำสั่งเดียวเขียนสองคำสั่งข้างบนเลยครับ #circle.rb class Circle attr_accessor :radious end กลับมาดูความแตกต่างของ class variable และ instance variable โดยดูจากตัวอย่าง class Circle attr_accessor :radious def count=(c) @@count = c end def count @@count end end circle_1 = Circle.new circle_2 = Circle.new circle_1.radious = 1 circle_2.radious = 2 puts circle_1.radious #=> 1 puts circle_2.radious #=> 2 circle_1.count = 1 circle_2.count = 2 puts circle_1.count #=> 2 puts circle_2.count #=> 2 จากการทดลองเราพบว่า circle_1 และ circle_2 จะใช้ class_variable ร่วมกัน เมื่อแก้ค่า count ที่ circle_1 หรือ circle_2 ค่าจึงออกมาเป็นแบบเดียว puts Circle.class_variables #=> @@count puts Circle.instance_variables #=> nil puts circle_1.instance_variables #=> @radious จากการทดลองต่อมา เราจะไม่พบ instance_variables เนื่องจาก @radious จะเกิดขึ้นก็ต่อเมื่อมีการเรียกใช้ method radious = แล้วเท่านั้น ปัญหาต่อมาคือ เราไม่สามารถรู้จำนวนวงกลม ถ้าเราไม่ประกาศ circle ขึ้นมาซักหนึ่งอันก่อน ทางแก้คือทำให้ method count กลายเป็น class method โดยใส่คำว่า self ลงไป class Circle attr_accessor :radious def count=(c) @@count = c end def self.count @@count end end circle_1 = Circle.new circle_1.count = 2 puts Circle.count #=> 2 จะเห็นว่าเราสามารถรู้ค่าของ count ได้โดยไม่ต้องประกาศ circle ขึ้นมาอีกตัว ถ้าต้องการให้ ruby เขียน code แทนให้ลองทำแบบนี้ครับ class Circle attr_accessor :radious class << self; attr_accessor :count end end แบบนี้ทั้ง count และ count= จะเป็น class variable ทั้งคู่ สรุปว่าตอนนี้ ruby ของเรามี * **class variable** เป็นตัวแปรของ class ทุก instance จะใช้ตัวแปรนี้ร่วมกัน * **class method** เป็น method ของ class เช่นเดียวกับ class variable * **instance variable** เป็นตัวแปรที่จะใช้ได้เมื่อ class ถูกประกาศขึ้นมาแล้ว * **instance method** ใช้ได้แบบเดียวกับ instance variable เลือกใช้งานกันตามความเหมาะสมนะครับ
blog comments powered by Disqus