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

เชี่ยวชาญ Yield และ Yield_Self ใน Ruby: คู่มือฉบับสมบูรณ์

คำว่า "yield" ใน Ruby หมายถึงอะไร? และมันทำอะไรอย่างแน่ชัด?

จริงๆ แล้ว...

Yield เป็นคีย์เวิร์ด (หมายถึงมันเป็นส่วนหลักของภาษา) และใช้ภายในเมธอดสำหรับเรียกบล็อก (block)

นี่คือสิ่งที่คุณต้องรู้:

  • การเรียกบล็อกจะรันโค้ดภายในบล็อกนั้น (เหมือนเรียกเมธอด)
  • Yield สามารถส่งอาร์กิวเมนต์จำนวนเท่าไรก็ได้ไปยังบล็อก
  • ค่าส่งคืนของบล็อกจะกลายเป็นค่าส่งคืนของ yield

คุณต้องเข้าใจบล็อก (blocks) เพื่อให้สิ่งนี้เข้าใจได้

คุณสามารถคิดถึงบล็อกได้ว่าเป็นเมธอดที่ไม่มีชื่อ ที่สามารถส่งผ่านเป็นอาร์กิวเมนต์เพิ่มเติมให้เมธอดอื่นๆ

ตัวอย่าง:

def make_salad
  yield "lettuce"
  yield "carrots"
  yield "olive oil"
end
make_salad { |ingredient| puts "Adding #{ingredient} to salad!" }

นี่เรียกบล็อก 3 ครั้ง ผลลัพธ์คือ:

Adding lettuce to salad!
Adding carrots to salad!
Adding olive oil to salad!

นั่นคือหัวใจของ yield คือเหมือนเรียกเมธอด แตแทนที่จะเรียกเมธอด คุณเรียกบล็อก

เราไม่มีชื่อสำหรับบล็อก ดังนั้นคีย์เวิร์ดนี้จัดการเรื่องนั้น

ตอนนี้:

มาสำรวจว่าจะเกิดอะไรขึ้น หากคุณไม่มีบล็อกให้เรียก

Yield โดยไม่มีบล็อก == ข้อความข้อผิดพลาด

หากคุณเรียก yield โดยไม่มีบล็อก แล้วคุณจะได้ข้อผิดพลาด

ตัวอย่าง:

def write_code
  yield
end
write_code # LocalJumpError: no block given (yield)

ข้อผิดพลาดนี้ชัดเจน "no block given" หมายความว่าการเรียกเมธอด write_code ไม่ได้ให้บล็อกมา

คุณสามารถป้องกันข้อผิดพลาดนี้ได้อย่างไร?

แบบนี้:

def write_code
  yield if block_given?
end

เมธอด block_given? ตรวจสอบว่ามีบล็อกให้หรือไม่ และสิ่งนี้อนุญาตให้คุณ yield ก็ต่อเมื่อเป็นจริง

ทำไมต้องใช้ Yield?

การใช้ yield เปิดใช้งานบล็อก

เราใช้บล็อกเพื่อส่งชิ้นส่วนของโค้ดเป็นส่วนหนึ่งของการเรียกเมธอด

นั่นช่วยได้เมื่อ:

  • คุณต้องการเขียนฟังก์ชัน logging แบบทั่วไป ที่บันทึกว่าชิ้นโค้ดหนึ่งใช้เวลานานเท่าไร
  • คุณต้องการรันโค้ดบางอย่างเมื่อเมธอดเสร็จ (เหมือน "callbacks" ใน Javascript)
  • คุณต้องการ "lazy code" โค้ดที่รันก็ต่อเมื่อจำเป็น และสามารถปรับแต่งโดยผู้ใช้ (ตัวอย่างอ่านเกี่ยวกับเมธอด Hash#fetch)

ดี!

Yield_Self — ความแตกต่างคืออะไร?

คุณอาจพบเมธอด yield_self ใหม่นี้ และคิดว่ามันเกี่ยวข้องกับ yield

จริงๆ แล้ว ไม่เกี่ยวข้อง

แม้ yield(self) ก็แตกต่าง เพราะ self หมายถึงออบเจ็กต์ปัจจุบัน

ที่ yield_self ซึ่งถูกเพิ่มใน Ruby 2.5 หมายถึงออบเจ็กต์ที่เรากำลังเรียกเมธอดอยู่

การใช้งานที่ดีสำหรับเมธอดนี้?

ใช้ทุกครั้งที่คุณต้องการเชนเมธอด (chain methods) และทำบางอย่างกับออบเจ็กต์ที่คุณเรียก yield_self อยู่

ขณะส่งคืนผลลัพธ์ แทนที่จะส่งคืนออบเจ็กต์ต้นฉบับ

ตัวอย่าง:

n_squared = ->(n) { n ** 2 }
2 .yield_self(&n_squared)
  .yield_self(&n_squared)
# 16

ใน Ruby 2.6 มีอีเลียส (alias) สำหรับ yield_self คือเมธอด then

แตอย่าสับสนกับ yield ปกติของคุณ

โอเค?

Yield ใน Rails

ผมควรให้การกล่าวถึงการใช้ yield ใน Rails และเทมเพลตเอนจินด้วย

คุณจะพบ yield ภายในเลย์เอาต์ (layouts)

Rails แทนที่มันด้วยเนื้อหาของวิวที่คุณกำลังเรนเดอร์

ไม่มี yield เท่ากับเลย์เอาต์ว่าง!

นั่นคือวิธีที่เลย์เอาต์และวิวของคุณถูกรวมเข้าด้วยกัน

สรุป

คุณได้เรียนรู้เกี่ยวกับคีย์เวิร์ด yield ใน Ruby แล้ว! ทุกอย่างคือ มันคืออะไร ทำงานอย่างไร และทำไมมันสำคัญ

ตอนนี้ลองใช้ในโค้ด Ruby ของคุณดูสิ

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