ค่าคงที่ใน Ruby คืออะไร
ค่าคงที่คือตัวแปรประเภทหนึ่งที่ขึ้นต้นด้วยตัวพิมพ์ใหญ่เสมอ กำหนดได้เฉพาะ ภายนอก ของเมธอด เว้นแต่คุณจะใช้ metaprogramming
ค่าคงที่ใช้สำหรับค่าที่ไม่ควรเปลี่ยนแปลง แต่ Ruby ไม่ได้ป้องกันคุณจากการเปลี่ยนแปลง
หน้าตาเป็นแบบนี้ :
FRUIT = "orange"
ตอนนี้ :
เนื่องจากค่าคงที่เป็นหัวข้อสำคัญ เราจะมาดูรายละเอียดในบทความนี้!
วิธีการกำหนดค่าคงที่
ค่าคงที่ไม่ต้องการสัญลักษณ์หรือไวยากรณ์พิเศษใด ๆ เพื่อประกาศ คุณเพียงแค่ต้องทำให้ตัวอักษรตัวแรกเป็นตัวพิมพ์ใหญ่
ต่อไปนี้คือค่าคงที่ที่ถูกต้อง :
ABC = 1 Goo = 2 Foo = 3
สังเกตว่าคุณไม่สามารถกำหนดค่าคงที่ภายในเมธอดได้
คุณจะได้รับข้อความแสดงข้อผิดพลาดที่คลุมเครือนี้ :
def the_method ABC = 1 end # "dynamic constant assignment"
ดังนั้น เพียงแค่กำหนดค่าคงที่ของคุณภายนอกเมธอด โดยปกติเราต้องการให้มีคำจำกัดความคงที่ที่ด้านบนสุดของคลาสของคุณเพื่อให้มองเห็นได้ชัดเจน
class RubyBlog URL = "rubyguides.com" AUTHOR = "Jesus Castello" end
จากนั้นคุณสามารถเข้าถึงค่าคงที่เหล่านี้ได้ภายในเมธอดของคลาสหรือภายนอกคลาสโดยใช้ไวยากรณ์ต่อไปนี้:
p RubyBlog::AUTHOR # "Jesus Castello"
เราจะพูดถึงขอบเขตของค่าคงที่เพิ่มเติมในโพสต์นี้ โปรดคอยติดตาม!
ข้อผิดพลาดคงที่ที่ไม่ได้กำหนดค่าเริ่มต้น
ข้อผิดพลาดทั่วไปที่คุณอาจได้รับคือ:
puts Foo # "uninitialized constant Foo (NameError)"
ฉันต้องการให้คุณแปลข้อผิดพลาดนี้ในใจว่า “ไม่พบค่าคงที่”
จุดสำคัญอย่างหนึ่งในการทำความเข้าใจข้อผิดพลาดนี้คือคลาส Ruby เป็นค่าคงที่
ตัวอย่าง :
Array String Hash
เป็นค่าคงที่เนื่องจากตัวอักษรตัวแรกเป็นตัวพิมพ์ใหญ่
เมื่อคุณกำหนดคลาส สิ่งที่คุณทำจริงๆ คือการสร้าง Class
วัตถุซึ่งถูกกำหนดให้เป็นค่าคงที่
ค่าคงที่กลายเป็นชื่อคลาส
เหตุใดจึงสำคัญ
เนื่องจากสาเหตุที่เป็นไปได้มากที่สุดที่คุณเห็นข้อผิดพลาด "ค่าคงที่ที่ไม่ได้กำหนดค่าเริ่มต้น" ก็คือคุณลืม require
ไฟล์หรืออัญมณีที่กำหนดค่าคงที่
หรือบางทีคุณอาจสะกดชื่อค่าคงที่ผิด
ดังนั้นจงจับตาดูให้ดี
ค่าคงที่เปลี่ยนได้
ดังที่ได้กล่าวไว้ในบทนำ ค่าคงที่ของ Ruby สามารถเปลี่ยนแปลงได้
ตัวอย่าง :
ABC = 1 ABC = 2
แต่คุณจะเห็นข้อความเตือนนี้:
2: warning: already initialized constant ABC
โปรแกรมของคุณยังคงทำงานได้ดี แต่คุณต้องการหลีกเลี่ยงสิ่งนี้
ไม่มีทางที่จะป้องกันไม่ให้ค่าคงที่เปลี่ยนแปลงได้ เนื่องจากตัวแปรใน Ruby ไม่ใช่คอนเทนเนอร์ แต่เป็นเพียงตัวชี้ไปยังวัตถุ
หรือฉลากได้ตามต้องการ
สิ่งที่ดีที่สุดที่คุณสามารถทำได้คือการใช้วัตถุที่ไม่เปลี่ยนรูป
ตัวอย่าง :
AUTHOR = "Jesus Castello".freeze AUTHOR << "o" # RuntimeError: can't modify frozen String
บทความที่เกี่ยวข้อง :การกลายพันธุ์ของทับทิม &วิธีการแช่แข็ง
ในตัวอย่างนี้ คุณยังสามารถเปลี่ยนสิ่งที่ AUTHOR
ค่าคงที่ชี้ไปที่สิ่งเดียวที่ หยุด
ปกป้องคุณจากการเปลี่ยนแปลงของวัตถุเอง
วิธีการคงที่
มีวิธีการสองสามวิธีที่ใช้กับค่าคงที่:
วิธีการ | คำอธิบาย |
---|---|
ค่าคงที่ | ส่งคืนอาร์เรย์ของสัญลักษณ์ที่แสดงค่าคงที่ที่กำหนดไว้ในคลาส |
const_get | คืนค่าสำหรับค่าคงที่ ใช้สัญลักษณ์หรือสตริงเป็นพารามิเตอร์ |
const_set | ตั้งค่าสำหรับค่าคงที่ รับสองพารามิเตอร์:ชื่อคงที่เป็นสัญลักษณ์ &ค่าคงที่ |
const_missing | เหมือนกับ method_missing แต่สำหรับค่าคงที่ |
const_defined? | คืนค่า จริง หากค่าคงที่ที่กำหนด (เป็นสัญลักษณ์) ถูกกำหนดไว้แล้ว |
remove_const | ลบค่าคงที่ |
private_constant | ทำให้ค่าคงที่ส่วนตัวไม่สามารถเข้าถึงได้นอกชั้นเรียนด้วย Class::ABC ไวยากรณ์ |
มีเทคนิค metaprogramming สองสามอย่างที่คุณสามารถทำได้โดยใช้วิธีการเหล่านี้
ตัวอย่าง :
module Food class Bacon; end class Chocolate; end end puts "Classes defined inside #{Food}:" puts Food.constants
คุณสามารถใช้สตริงเช่น "อาร์เรย์" และรับคลาสจริง:
array_class = Object.const_get("Array")
แต่ระวังตัวด้วยเพราะผู้ใช้สามารถฉีดโค้ดได้หากสตริงนั้นมาจาก params
หรือรูปแบบอื่นๆ ของการป้อนข้อมูลของผู้ใช้
ใน Rails มีวิธีทำให้คงที่ซึ่งโดยทั่วไปแล้วจะทำ const_get
สำหรับคุณ แต่โปรดทราบว่าไม่มีการตรวจสอบความปลอดภัยใดๆ
สูตรโกง
ขอบเขตทับทิมคงที่
เมื่อคุณสร้างค่าคงที่นอกคลาสใดๆ ที่ระดับบนสุดของโค้ดของคุณ ค่าคงที่นั้นจะสามารถใช้ได้ทุกที่
ค่าคงที่ยังมีอยู่ในชั้นเรียนย่อย
class A FOO = 1 end class B < A def foo puts FOO end end B.constants # [:FOO]
ค่าคงที่ที่กำหนดนอกโมดูลหรือคลาสที่ซ้อนกันนั้นยังมีอยู่ในคลาสที่ซ้อนกันด้วย
module Food STORE_ADDRESS = "The moon" class Bacon def foo; puts STORE_ADDRESS; end end end fb = Food::Bacon.new fb.foo # "The moon"
การผสมโมดูล
ค่าคงที่จากโมดูลแบบผสมก็มีให้เช่นกัน:
module Mixin A = 123 end class Product include Mixin puts A end # 123
สังเกตว่าสิ่งนี้ใช้ได้เมื่อรวมโมดูลด้วย มันจะไม่ทำงานหากคุณกำลังขยายโมดูล
ตัวอย่าง :
class Product extend Mixin puts A end # uninitialized constant Product::A
เช่นกัน :
เมื่อคุณใช้เมธอดที่รวมมาจากโมดูล Ruby จะค้นหาค่าคงที่เริ่มต้นจากตำแหน่งที่กำหนดเมธอดนั้น
ตัวอย่าง :
module Parent def print_value VALUE end end class Child include Parent VALUE = 1 end # Works p Child::VALUE # uninitialized constant Parent::VALUE p Child.new.print_value
สิ่งที่ควรทราบ!
การซ้อนโมดูล
ฉันต้องการแสดงตัวอย่างเพิ่มเติมกับคลาสที่ซ้อนกัน (เหมือนกันสำหรับโมดูล)
class A FOO = 1 end class A::B class C puts FOO end end
สังเกต A::B
สัญกรณ์ที่นี่ซึ่งเราพยายามใช้เป็นทางลัด แต่ปัญหาคือคลาสนั้น C
จะไม่สามารถเข้าถึง FOO
โดยตรง
ด้วยเหตุผลดังกล่าว คุณจึงต้องการยึดติดประเภทนี้:
class A FOO = 1 end class A class B class C puts FOO end end end
ในตัวอย่างแรก คุณยังสามารถทำ ::A::FOO
เพื่อเข้าถึงค่าคงที่ แต่ถ้าชื่อคลาสเปลี่ยนไป คุณจะได้รับข้อผิดพลาด
::A::FOO
นี้ ::A::FOO
ไวยากรณ์ใช้งานได้เพราะมันบอกให้ Ruby ดูในขอบเขตระดับบนสุด โดยที่ค่าคงที่เช่น Array
&สตริง
ถูกกำหนดไว้แล้ว
วิดีโอ
สรุป
คุณได้เรียนรู้เกี่ยวกับค่าคงที่ Ruby ซึ่งเป็นตัวแปรประเภทหนึ่งที่มีพฤติกรรมที่น่าสนใจ คุณสามารถเปลี่ยนค่าของค่าคงที่ได้ แต่จะพิมพ์คำเตือน
คุณยังได้เรียนรู้ว่าชื่อคลาสเป็นค่าคงที่ &คุณควรหลีกเลี่ยง const_get
ด้วยการป้อนข้อมูลของผู้ใช้
หากคุณชอบโพสต์นี้ อย่าลืมแชร์ เพื่อให้คนอื่นเข้าใจการทำงานของค่าคงที่มากขึ้น