ผมพบว่าการใช้ ruby ในการเรียนรู้เรื่อง OOP เป็นเรื่องที่สนุกทีเดียว ทุกอย่างในภาษานี้เป็น Object ไปหมด แม้แต่ nil ยังเป็น object ด้วย ในตอนแรกผมมุ่งศึกษาตัว Rails เป็นหลัก และพบว่าหากไม่ใช่ Ruby แล้ว Rails คงเกิดได้ยากมาก
หากต้องการศึกษา rails ให้มากกว่านี้ผมต้องแม่นเรื่อง Object ของ Ruby ให้มากขึ้น และบทความนี้ผมจะใช้สำหรับเป็น Reference ของตัวเอง

ทดลองสร้าง 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
เลือกใช้งานกันตามความเหมาะสมนะครับ
| Attachment | Size |
|---|---|
| object1.png | 23.01 KB |
แปลกใจจัง จริงๆ เรื่องพวกนี้เป็นเรื่องพื้นฐาน ที่ควรจะต้องเรียนรู้และต้องเข้าใจมาเป็นอย่างดีอยู่ก่อนแล้ว ไม่เข้าใจว่า ไป focus ที่ rails ก่อนที่จะรู้เรื่องพวกนี้ ผมว่ามันผิด step ไปหน่อยนะ
ผมคิดว่าการศึกษาภาพรวมต้องมาก่อนการลงรายละเอียดน่ะครับ ส่วนตัวผมมองว่าอยากเรียนรู้ rails เพราะถ้าไม่มี rails คงไม่คิดศึกษา ruby ประกอบกับเคยเขียนภาษาอื่นมาแล้ว เลยคิดว่าคล้ายๆ กัน
ทีนี้พอได้ภาพรวมเราก็ลงรายละเอียดอีกขั้นหนึ่ง จึงมาศึกษา ruby มากขึ้น แล้วพบว่า object ของ ruby, java, objective-c, php มันต่างกัน ผมอาจจะลงมาศึกษา ruby ช้าไปหน่อย แต่คิดว่าคงศึกษาไปพร้อมๆ กันกับ rails
อีกประเด็นหนึ่งผมคิดว่าต่อให้ไม่รู้เรื่องพวกนี้ก็สามารถใช้ rails แบบทั่วไปได้แล้วน่ะครับ ต้องบริหารความสนุกในการเรียนรู้คู่ไปด้วย :) rails มันมี wow มากมายช่วยเพิ่มความสนุกได้มากเลยทีเดียว
Post new comment