Object ในภาษา ruby

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

หากต้องการศึกษา rails ให้มากกว่านี้ผมต้องแม่นเรื่อง Object ของ Ruby ให้มากขึ้น และบทความนี้ผมจะใช้สำหรับเป็น Reference ของตัวเอง

object

ทดลองสร้าง Class Circle เพื่อเป็นพิมพ์เขียวให้กับ Object circle

  1. #circle.rb
  2. class Circle
  3.   @@count
  4.   @radious
  5.   @circle
  6. end
  7.  
  8. puts Circle.class_variables  #=> @@count
  9. puts Circle.instance_variables #=> @circle@radious
  10. puts Circle.count #=> undefined method `count'

@@count เป็นตัวแปรของ class หรือเรียกว่า class variable

ส่วน @radious และ @circle เป็นตัวแปรของ object เมื่อ object ถูกสร้างขึ้น หรือเรียกว่า instance variable ซึ่งจะอธิบายความแตกต่างอีกทีหนึ่ง

สังเกตุ error ของบรรทัดสุดท้าย เราจะพบว่า ruby ไม่สามารถอ้างอิงไปที่ตัวแปรโดยตรง แต่จะถามหา method เลย แปลว่าทุกอย่างต้องผ่าน method ที่นี้ลองสร้าง method สำหรับแก้ไขตัวแปร @radious

  1. #circle.rb
  2. class Circle
  3.   def radious=(r)
  4.      @radious = r
  5.   end
  6.  
  7.   def radious
  8.      return @radious
  9.   end
  10. end
  11.  
  12. circle = Circle.new
  13. puts circle.radious #=> nil
  14. circle.radious = 4
  15. puts circle.radious #=> 4

เนื่องจาก ruby เป็นภาษาแบบ dynamic การให้โปรแกรมเขียนโปรแกรมจึงเป็นเรื่องปกติมากๆ เช่นในกรณีนี้เราจะมีคำสั่ง

attr_reader :radious ใช้เขียนคำสั่ง def radious ... attr_writer :radious ใช้เขียนคำสั่ง def radious=(r) ... attr_accessor :radious ใช้คำสั่งเดียวเขียนสองคำสั่งข้างบนเลยครับ

  1. #circle.rb
  2. class Circle
  3.   attr_accessor :radious
  4. end

กลับมาดูความแตกต่างของ class variable และ instance variable โดยดูจากตัวอย่าง

  1. class Circle
  2.   attr_accessor :radious
  3.  
  4.   def count=(c)
  5.     @@count = c
  6.   end
  7.  
  8.   def count
  9.     @@count
  10.   end
  11. end
  12.  
  13. circle_1 = Circle.new
  14. circle_2 = Circle.new
  15.  
  16. circle_1.radious = 1
  17. circle_2.radious = 2
  18. puts circle_1.radious #=> 1
  19. puts circle_2.radious #=> 2
  20.  
  21. circle_1.count = 1
  22. circle_2.count = 2
  23. puts circle_1.count #=> 2
  24. puts circle_2.count #=> 2

จากการทดลองเราพบว่า circle_1 และ circle_2 จะใช้ class_variable ร่วมกัน เมื่อแก้ค่า count ที่ circle_1 หรือ circle_2 ค่าจึงออกมาเป็นแบบเดียว

  1. puts Circle.class_variables #=> @@count
  2. puts Circle.instance_variables #=> nil
  3. puts circle_1.instance_variables #=> @radious

จากการทดลองต่อมา เราจะไม่พบ instance_variables เนื่องจาก @radious จะเกิดขึ้นก็ต่อเมื่อมีการเรียกใช้ method radious = แล้วเท่านั้น

ปัญหาต่อมาคือ เราไม่สามารถรู้จำนวนวงกลม ถ้าเราไม่ประกาศ circle ขึ้นมาซักหนึ่งอันก่อน

ทางแก้คือทำให้ method count กลายเป็น class method โดยใส่คำว่า self ลงไป

  1. class Circle
  2.   attr_accessor :radious
  3.  
  4.   def count=(c)
  5.     @@count = c
  6.   end
  7.  
  8.   def self.count
  9.     @@count
  10.   end
  11. end
  12.  
  13. circle_1 = Circle.new
  14.  
  15. circle_1.count = 2
  16. puts Circle.count #=> 2

จะเห็นว่าเราสามารถรู้ค่าของ count ได้โดยไม่ต้องประกาศ circle ขึ้นมาอีกตัว

ถ้าต้องการให้ ruby เขียน code แทนให้ลองทำแบบนี้ครับ

  1. class Circle
  2.   attr_accessor :radious
  3.   class << self;
  4.     attr_accessor :count
  5.   end
  6. end

แบบนี้ทั้ง count และ count= จะเป็น class variable ทั้งคู่

สรุปว่าตอนนี้ ruby ของเรามี

  • class variable เป็นตัวแปรของ class ทุก instance จะใช้ตัวแปรนี้ร่วมกัน
  • class method เป็น method ของ class เช่นเดียวกับ class variable
  • instance variable เป็นตัวแปรที่จะใช้ได้เมื่อ class ถูกประกาศขึ้นมาแล้ว
  • instance method ใช้ได้แบบเดียวกับ instance variable

เลือกใช้งานกันตามความเหมาะสมนะครับ

AttachmentSize
object1.png23.01 KB

แปลกใจจัง จริงๆ เรื่องพวกนี้เป็นเรื่องพื้นฐาน ที่ควรจะต้องเรียนรู้และต้องเข้าใจมาเป็นอย่างดีอยู่ก่อนแล้ว ไม่เข้าใจว่า ไป focus ที่ rails ก่อนที่จะรู้เรื่องพวกนี้ ผมว่ามันผิด step ไปหน่อยนะ

ผมคิดว่าการศึกษาภาพรวมต้องมาก่อนการลงรายละเอียดน่ะครับ ส่วนตัวผมมองว่าอยากเรียนรู้ rails เพราะถ้าไม่มี rails คงไม่คิดศึกษา ruby ประกอบกับเคยเขียนภาษาอื่นมาแล้ว เลยคิดว่าคล้ายๆ กัน

ทีนี้พอได้ภาพรวมเราก็ลงรายละเอียดอีกขั้นหนึ่ง จึงมาศึกษา ruby มากขึ้น แล้วพบว่า object ของ ruby, java, objective-c, php มันต่างกัน ผมอาจจะลงมาศึกษา ruby ช้าไปหน่อย แต่คิดว่าคงศึกษาไปพร้อมๆ กันกับ rails

อีกประเด็นหนึ่งผมคิดว่าต่อให้ไม่รู้เรื่องพวกนี้ก็สามารถใช้ rails แบบทั่วไปได้แล้วน่ะครับ ต้องบริหารความสนุกในการเรียนรู้คู่ไปด้วย :) rails มันมี wow มากมายช่วยเพิ่มความสนุกได้มากเลยทีเดียว

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.

Post new comment

The content of this field is kept private and will not be shown publicly.
CAPTCHA
This question is for testing whether you are a human visitor and to prevent automated spam submissions.
Image CAPTCHA
Copy the characters (respecting upper/lower case) from the image.