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

ตรวจสอบการนิยามตัวแปรใน Ruby: คู่มือง่ายๆ

Ruby มีคีย์เวิร์ด defined? ที่ช่วยตรวจสอบว่าตัวแปรถูกนิยามหรือไม่

ถ้าตัวแปรมีอยู่ คุณจะได้ type ของมัน:

apple = 1
defined?(apple) # "local-variable"

ถ้าไม่มี จะได้ nil:

defined?(bacon) # nil

เหมือน operator typeof ของ JavaScript หากต้องการรู้ class ของออบเจกต์ ใช้เมธอด class แทน

จุดน่าสนใจบางจุด:

  • defined? เป็น คีย์เวิร์ด ไม่ใช่ เมธอด
  • defined? เป็นหนึ่งในสิ่งน้อยใน Ruby ที่ลงท้ายด้วยเครื่องหมายคำถาม แต่ไม่ปฏิบัติตาม convention ที่คืน true หรือ false
  • defined? แยกแยะได้ระหว่างค่า nil กับตัวแปรที่ไม่เคยถูกตั้งค่า

ลักษณะพิเศษเหล่านี้ทำให้คีย์เวิร์ดนี้คุ้มค่าที่จะเรียนรู้

วิธีที่ดีกว่าในการตรวจสอบตัวแปรที่นิยามแล้ว

คีย์เวิร์ดนี้มีประโยชน์ แต่มีปัญหาบางอย่าง

ทำไม?

เพราะ operator precedence ต่ำ

หากคุณทำแบบนี้:

defined? orange && orange.size

ผลลัพธ์คือ "expression"

เพราะ orange && orange.size ถูกตีความเป็นอาร์กิวเมนต์ของ defined?

วิธีที่ถูกต้องคือ:

defined?(orange) && orange.size

Ruby มีวิธีอื่นในการตรวจสอบว่าตัวแปรถูกนิยามหรือไม่

สำหรับ local variables:

local_variables.include?(:orange)

สำหรับ instance variables:

instance_variable_defined?("@food")

แตคุณไม่ควรใช้สิ่งเหล่านั้น

ใน 99% ของกรณี หาก local variable หายไป หมายถึงคุณ typo หรือใครลืมนิยามตัวแปรนั้น

instance variables แล้วล่ะ?

Instance variables ที่ไม่ได้นิยามจะเป็น nil เสมอ ดังนั้นคุณอยากตรวจสอบนั่น

ลอง "safe navigator operator" (Ruby 2.3+) ซึ่งเรียกเมธอดก็ต่อเมื่อตัวแปรไม่ใช่ nil

ตัวอย่าง:

if @user&.country == "Spain"
  # ...
end

สิ่งนี้เทียบเท่ากับ:

if @user && @user.country == "Spain"
  # ...
end

วิธีเหล่านี้ไม่ universal เท่า defined? แต่ predictable กว่าและ error-prone น้อยกว่า

ตรวจสอบว่าเมธอดถูกนิยามหรือไม่

คุณสามารถใช้ defined? ตรวจสอบเมธอดได้ แต่ไม่ค่อย practical

ตัวอย่าง:

defined?(puts) # "method"

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

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

[].defined?(:size) # undefined method `defined?' for []:Array

คุณกำลังหาเมธอด respond_to?

วิธีใช้:

[].respond_to?(:size) # true
[].respond_to?(:orange) # false

ตรวจสอบว่าคลาสมีอยู่หรือไม่

ตัวอย่าง:

defined?(Object) # "constant"
defined?(A) # nil

ตัวเลือกที่ดีกว่าคือใช้เมธอด const_defined?

แบบนี้:

Object.const_defined?(:String) # true
Object.const_defined?(:A) # false

สรุป

คุณเรียนรู้วิธีง่ายๆ ในการตรวจสอบว่าตัวแปร คลาส หรือเมธอดมีอยู่จริง!

เมื่อทำงานกับตัวแปร สิ่งที่คุณต้องการส่วนใหญ่คือตรวจสอบ nil แทนการตรวจสอบว่าตัวแปรนิยามหรือไม่ หรือดีกว่านั้น แปลงตัวแปรเป็นคลาสที่รู้จักด้วย conversion method

หวังว่าบทความนี้จะมีประโยชน์! หากเป็นเช่นนั้นกรุณา แชร์ ให้ผู้คนอีกมากขึ้นได้เพลิดเพลินไปกับมัน