Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> Ruby

เข้าใจคีย์เวิร์ด self ใน Ruby: คู่มือชัดเจนสำหรับการใช้งานอย่างมีประสิทธิภาพ

หากคุณกำลังเรียน Ruby คุณอาจพบว่าการใช้คีย์เวิร์ด "self" น่าสับสนมาก

มันทำงานอย่างไร?

self คืออะไร จริงๆ แล้ว?

มันคือ คีย์เวิร์ดของ Ruby ที่ให้คุณเข้าถึงออบเจ็กต์ปัจจุบัน (current object)

หากคุณไม่รู้ว่าออบเจ็กต์คืออะไร ดูวิดีโอที่ผมทำไว้ให้คุณ มันเกี่ยวกับ Object-Oriented Programming

"ออบเจ็กต์ปัจจุบัน" นี้ขึ้นอยู่กับบริบท (context)

บริบท?

ใช่ บริบทคือที่ที่โค้ดของคุณอยู่ในเวลาใดเวลาหนึ่ง

ตัวอย่าง:

หากโค้ดของคุณอยู่ภายใน instance method self คือ อินสแตนซ์ ของคลาสนั้น กล่าวคือ self คือออบเจ็กต์

คุณสามารถเห็นได้ด้วยตัวเอง

รันโค้ดนี้:

def coffee
  puts self
end
coffee # main

โค้ดนี้กำหนดและเรียกเมธอด coffee ซึ่งพิมพ์ค่าของ self

ทำไมมันพิมพ์ main?

เพราะนี่คือชื่อของออบเจ็กต์ระดับบนสุด (top-level object) มันคือออบเจ็กต์ที่คุณจะพบเมธอดทั้งหมดที่กำหนด นอก คลาส

เหมือนเมธอด coffee ของเราที่นี่

แตถ้าคุณกำหนดเมธอดภายในคลาสชื่อ Cat แล้ว self จะเป็นออบเจ็กต์ Cat

เห็นได้ที่นี่:

class Cat
  def meow
    puts self
  end
end
Cat.new.meow # <Cat:0x7a14c5>

จากตัวอย่างเหล่านี้ เราสามารถบอกได้ว่าค่าของ self เปลี่ยนไปขึ้นอยู่กับที่คุณใช้มัน

ตอนนี้:

ผมเชื่อว่าคุณสามารถเข้าใจอะไรก็ตามได้ดีขึ้น โดยการเข้าใจวัตถุประสงค์ของมัน

ทำไม self จึงมีประโยชน์?

มาดูตัวอย่างบ้าง

การใช้ Self เพื่อความชัดเจน (Disambiguation)

การใช้งาน self ที่ปฏิบัติจริงหนึ่งคือ เพื่อแยกแยะความแตกต่างระหว่างเมธอดและตัวแปรท้องถิ่น (local variable)

มันไม่ใช่ความคิดที่ดีที่จะตั้งชื่อตัวแปรและเมธอดเหมือนกัน แตถ้าคุณต้องทำงานกับสถานการณ์นั้น คุณจะสามารถเรียกเมธอดด้วย self.method_name

นี่คือสิ่งที่ผมหมายถึง:

class Example
  def do_something
    banana = "variable"
    puts banana
    puts self.banana
  end
  def banana
    "method"
  end
end
Example.new.do_something
# "variable" => puts banana
# "method" => puts self.banana

ที่นี่เรามีตัวแปรท้องถิ่น banana ภายในเมธอด do_something แตเราก็มีเมธอด banana ด้วย

ตัวแปรท้องถิ่นมีความสำคัญกว่า (takes priority)

นั่นคือเหตุผลที่เราต้องใช้ self ที่นี่ หากเราต้องการ เรียก เมธอด banana แทนที่จะ พิมพ์ ค่าของตัวแปร banana

ต่อไป:

มาดูกรณีใช้งานที่พบบ่อยกว่า... การกำหนดเมธอดระดับคลาส (Class-level methods)!

การใช้ Self เพื่อกำหนดเมธอดระดับคลาส

การใช้ self หมายเลข ONE ไม่ต้องสงสัย คือ การกำหนดเมธอดระดับคลาส

ผมมั่นใจว่าคุณเคยเห็นมัน

นี่คือการกำหนดเมธอด def self.method_name

เหมือนนี้:

class Salad
  def self.buy_olive_oil
    # ...
  end
end
Salad.buy_olive_oil

self ที่นี่เทียบเท่ากับ Salad ชื่อคลาส

ทำไมสิ่งนี้จึงมีประโยชน์?

เพราะเราไม่ต้องใช้ชื่อคลาสสำหรับการกำหนดเมธอดทุกตัว ทำให้โค้ดของเราง่ายต่อการเปลี่ยนแปลงหากเราเปลี่ยนคลาส

มันยังทำให้โค้ดมีเสียงน้อยลง (less noisy) และอ่านง่ายขึ้น

นั่นคือเหตุผลที่เราเขียน def self.buy_olive_oil แทน def Salad.buy_olive_oil

การใช้งาน Self อื่นๆ

ใช่!

ยังมีการใช้งาน self อื่นๆ อีกมาก ดังนั้นมันจึงเป็นสิ่งที่คุ้มค่าที่จะคุ้นเคย

ตัวอย่าง:

คุณสามารถใช้มันในเมธอดเพื่อเปรียบเทียบออบเจ็กต์ปัจจุบันกับออบเจ็กต์อื่น

อย่างนี้:

def ==(other)
  self == other
end

คุณยังสามารถใช้ self เพื่อจุดประสงค์ดีบัก (debugging) เพื่อค้นหาว่าคุณกำลังทำงานกับออบเจ็กต์ไหน

แบบนี้:

p self

หรือคุณสามารถใช้มันเป็นค่าส่งคืน (return value) เพื่อนำรูปแบบการออกแบบ (design patterns) เช่น Builder Design Pattern ไปใช้

ตัวอย่าง:

class Salad
  def initialize
    @ingredients = []
  end
  def add_nuts
    @ingredients << :nuts
    self
  end
end
my_salad = Salad.new.add_nuts

สรุป นี่คือรายการการใช้งาน self ที่มีประโยชน์:

  • กำหนดเมธอดระดับคลาส
  • ใช้เมธอดอินสแตนซ์เมื่อคุณมีตัวแปรท้องถิ่นชื่อเดียวกัน
  • ส่งคืน Self (builder pattern)
  • ดีบัก (Debugging)
  • เปรียบเทียบออบเจ็กต์ (==)
  • Default receiver of method calls

Self vs Itself

อีกหนึ่งสิ่งที่เราควรดูก่อนจบหัวข้อนี้

เมธอด Kernel#itself

มันคือเมธอดที่คุณสามารถเรียกบนออบเจ็กต์ และออบเจ็กต์จะส่งคืนตัวมันเอง

ตัวอย่าง:

[1,2,3,nil].select(&:itself) # [1, 2, 3]

ตัวอย่างนี้กรองค่า nil และ false ออก

การเข้าใจความแตกต่าง:

  • self เป็นคีย์เวิร์ด ค่าขึ้นอยู่กับ ที่ไหน ที่คุณใช้มัน
  • itself เป็นเมธอด ค่าขึ้นอยู่กับ อะไร ออบเจ็กต์ที่คุณใช้มัน (ใน 1.itself, 1 คือออบเจ็กต์)

หวังว่าจะมีประโยชน์

สรุป

คุณได้เรียนรู้เกี่ยวกับคีย์เวิร์ด self ของ Ruby ทุกอย่างแล้ว คือ มันคืออะไร ทำไมมันมีประโยชน์ และวิธีใช้มัน

ตอนถึงคุณลองทำดูสิ

ขอบคุณที่อ่าน! 🙂