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

เชี่ยวชาญ Ruby: ใช้คีย์เวิร์ด Alias เพื่อสร้าง Alias ของเมธอด

คุณสามารถตั้งชื่อทางเลือกให้กับเมธอด Ruby ได้สองวิธี:

  • alias (คีย์เวิร์ด)
  • alias_method

เนื่องจากทั้งสองทำสิ่งเดียวกันแต่วิธีการต่างเล็กน้อย จึงอาจทำให้สับสน

ภาพนี้สรุปความแตกต่าง:

เชี่ยวชาญ Ruby: ใช้คีย์เวิร์ด Alias เพื่อสร้าง Alias ของเมธอด

มาเรียนรู้ความแตกต่างเหล่านี้ให้ลึกซึ้งขึ้นกัน!

คีย์เวิร์ด alias

ก่อนอื่นคือ alias ซึ่งเป็นคีย์เวิร์ดของ Ruby (เหมือน if, def, class ฯลฯ)

รูปแบบการใช้งาน:

alias print_something puts
print_something 1

ตอนนี้การเรียก print_something จะเหมือนกับการเรียก puts ทุกประการ

เนื่องจาก alias เป็นคีย์เวิร์ด จึงมี ลักษณะพิเศษบางอย่าง:

  • มีไวยากรณ์เฉพาะตัว
  • ใช้ได้ทุกที่ในโค้ด
  • สามารถ alias ตัวแปร global ได้ (แต่ไม่ควรทำ!)

รูปแบบที่ถูกต้องของ alias:

  • alias a b
  • alias :a :b
  • alias :"#{}" :b

สังเกตว่า ไม่มีคอมม่าระหว่างอาร์กิวเมนต์ เหมือนเมธอดทั่วไป

Ruby คาดหวังว่า a และ b จะเป็นชื่อเมธอดที่ถูกต้อง ตัวแปรไม่ได้ทำงานที่นี่ หากต้องการใช้ตัวแปร ต้องทำแบบนี้…

ตัวอย่าง:

a = :print_something
b = :puts
alias :"#{a}" :"#{b}"

แต่รูปแบบนี้ดูไม่สวย ดังนั้นอาจอยากใช้ alias_method สำหรับชื่อเมธอดแบบไดนามิกแทน

เมธอด alias_method

ต่อมา:

คือ alias_method ซึ่งเป็นเมธอดที่นิยามอยู่บน Module

คุณสามารถใช้เมธอดนี้ได้เฉพาะระดับคลาสและโมดูลเท่านั้น ไม่สามารถใช้ภายในเมธอดอินสแตนซ์ได้

คำอธิบายจากเอกสาร:

alias_method: "ทำให้ new_name เป็นสำเนาใหม่ของเมธอด old_name สามารถใช้เพื่อรักษาการเข้าถึงเมธอดที่ถูก override"

ตัวอย่าง:

class Foo
  alias_method :print_something, :puts
end

จะ alias print_something ไปที่ puts ภายใน Foo

คุณสามารถใช้สตริงเป็นอาร์กิวเมนต์ของ alias_method ได้

ตัวอย่าง:

class Foo
  alias_method "print_something", "puts"
end

alias เทียบกับ alias_method

คุณได้เห็นภาพรวมของ alias และ alias_method แล้ว

แต่ความแตกต่างจะสำคัญเมื่อไหร่?

  1. เมื่อนิยาม alias สำหรับ ชื่อเมธอดที่สร้างแบบไดนามิก (เช่น "abc#{rand}")
  2. เมื่อนิยาม alias ภายในเมธอด

การ alias ชื่อเมธอดแบบไดนามิกทำได้ด้วยคีย์เวิร์ด alias แต่ต้องใช้สัญลักษณ์ที่ interpolated

กับ alias_method คุณจะได้อาร์กิวเมนต์ที่ยืดหยุ่นกว่า

ตัวอย่าง:

class Cat
  def speak
    "meow"
  end
  alias_method "#{name.downcase}_speak", :speak
end
p Cat.new.cat_speak # "meow"

ตอนนี้:

หากต้องการนิยาม alias ภายในเมธอด จะได้ข้อผิดพลาดนี้:

undefined method 'alias_method' for # (NoMethodError)

เพราะคุณทำงานอยู่ภายในออบเจกต์ ไม่ใช่คลาส!

ภายในเมธอดอินสแตนซ์ คุณไม่เข้าถึงเมธอดที่นิยามใน Module ซึ่งเป็นที่ที่ alias_method ถูกนิยามอยู่

วิธีแก้ไขที่เป็นไปได้:

def enable_aliased_methods
  self.class.send(:alias_method, :x, :testing)
end

ใช้ alias:

def enable_aliased_methods
  alias :x :testing
end

ความแตกต่างสำคัญหนึ่งจุด:

  • เมธอดที่นิยามโดย alias จะเป็นของคลาสที่ใช้ alias
  • เมธอดที่นิยามโดย alias_method จะเป็นของ self คือคลาสปัจจุบันในขณะที่โค้ดรัน

นี่คือเหตุผลที่มันสำคัญ:

หากคุณเรียกเมธอดบนคลาสแม่ที่ใช้คีย์เวิร์ด alias…

การ alias จะเกิดขึ้นบนคลาสแม่ ไม่ใช่คลาสที่เรียกเมธอด

ตัวอย่าง:

class Food
  def create_alias
    alias print_on_screen puts
  end
end
class Apple < Food
end
Apple.new.create_alias

แต่ถ้าใช้ alias_method เมธอดจะถูก alias เฉพาะบน Apple เท่านั้น

การ Alias สร้างสำเนาของเมธอด

ตามคำอธิบายของ alias_method และ alias (คีย์เวิร์ด) Ruby จะสร้างสำเนาของเมธอด

ไม่ใช่แค่ชื่อใหม่

แต่ เป็นสำเนาจริงของเมธอด

สิ่งนี้มีผลกระทบทางปฏิบัติ:

def bacon
  123
end
alias :x :bacon
x # 123
bacon # 123

เรา alias x ไปที่ bacon ดูสิเกิดอะไรขึ้นถ้าปรับนิยาม bacon ใหม่:

def bacon
  234
end
x # 123
bacon # 234

เมธอด x คงเดิม แต่ bacon คืนค่าใหม่!

สิ่งนี้อาจทำให้ประหลาดใจหากคุณ include โมดูลเข้าไปในคลาสหลังจาก alias เมธอดแล้ว

วิดีโอสอน

สรุป

โดยทั่วไปผมชอบ alias_method มากกว่า เพราะมันเป็นเมธอดจริง

ในขณะที่คีย์เวิร์ด alias มีลักษณะพิเศษบางอย่างที่ต้องจดจำและระวัง

คุณเรียนรู้อะไรใหม่ไหม?

แชร์บทความนี้ให้เพื่อน Ruby ของคุณ เพื่อให้พวกเขาเรียนรู้ได้เช่นกัน!