หากคุณใช้ Ruby มาระยะหนึ่งแล้ว คุณอาจสงสัยว่าบางสิ่งทำงานอย่างไร
วิธีหนึ่งในการเจาะลึกเข้าไปใน Ruby internals คือการอ่านซอร์สโค้ดที่ทำให้ใช้งานได้ แม้ว่าคุณจะไม่รู้ C คุณก็ยังสามารถหยิบสิ่งที่น่าสนใจบางอย่างได้
ซอร์สโค้ดสามารถพบได้ใน github repo สำหรับ Ruby
ตามหลักการแล้ว คุณต้องการใช้เครื่องมืออย่าง Codequery ซึ่งช่วยให้คุณค้นหาชื่อคลาสและเมธอดได้อย่างง่ายดาย
สำรวจคลาสหลัก
การสำรวจส่วนใหญ่ของคุณจะเกิดขึ้นในโฟลเดอร์รูท ที่ซึ่งคุณจะพบซอร์สโค้ดสำหรับคลาสหลักทั้งหมด เช่น Object
ใน object.c
หรือ Array
ใน array.c
.
มาดู hash.c
. กัน .
หากคุณเลื่อนลงมาจนสุดบรรทัดที่ 4468 คุณจะเห็นชื่อที่น่าจะคุ้นเคย
มาเริ่มกันเลย :
rb_cHash =rb_define_class("Hash", rb_cObject);
ในบรรทัดนี้ Hash
คลาสถูกกำหนดโดย rb_define_class
การทำงาน. อาร์กิวเมนต์ที่สอง (rb_cObject
) เป็นซูเปอร์คลาสสำหรับคลาสนี้
หากคุณต้องการเรียนรู้ว่ากระบวนการกำหนดชั้นเรียนทำงานอย่างไร ให้ค้นหา rb_define_class
.
ส่วนแรกจาก rb_define_class
ตรวจสอบว่ามีการกำหนดคลาสแล้วหรือไม่
if (rb_const_defined(rb_cObject, id)) { // ...}
ข้างในนั้น if
บล็อก Ruby ตรวจสุขภาพจิตบางอย่าง เช่น ตรวจสอบว่าเรากำลังทำงานกับชั้นเรียนที่กำหนดไว้แล้ว
หากไม่ได้กำหนดคลาส คลาสจะถูกกำหนดดังนี้:
klass =rb_define_class_id(id, super);st_add_direct(rb_class_tbl, id, klass);rb_name_class(klass, id);rb_const_set(rb_cObject, id, klass);rb_class_inherited(super, klass);>คุณสามารถอ่านคำจำกัดความของวิธีการทั้งหมดเหล่านี้ได้ แต่ฉันคิดว่ามันค่อนข้างอธิบายตนเองได้
ใน
st_add_direct
ส่วน 'st' หมายถึง 'ตารางสัญลักษณ์' และนี่เป็นเพียงตารางแฮชrb_const_set
ฟังก์ชั่นตั้งค่าคงที่บนObject
คลาสนี้จะทำให้คลาสนี้พร้อมใช้งานได้ทุกที่และ
rb_class_inherited
เรียกinherited
ของ superclass คุณสามารถค้นหาเอกสารสำหรับวิธีนี้ได้ที่นี่ส่วนถัดไปของรหัสประกอบด้วยคำจำกัดความของวิธีการ MRI ใช้
rb_define_method
ที่จะทำเช่นนั้นนี่คือตัวอย่าง :
rb_define_method(rb_cHash,"index", rb_hash_index, 1);rb_define_method(rb_cHash,"size", rb_hash_size, 0);rb_define_method(rb_cHash,"length", rb_hash_size, _method(rb_hash_size, 0);rb_hash_size, 0);rb_define_method(rb_cHash,"length" , rb_hash_empty_p, 0);การโต้แย้งมีลักษณะเช่นนี้ :
- อาร์กิวเมนต์แรกคือคลาสที่มีการกำหนดเมธอดนี้
- อาร์กิวเมนต์ที่สองคือชื่อเมธอด อาร์กิวเมนต์ที่สามคือฟังก์ชัน C ซึ่งใช้วิธีนี้จริง
- อาร์กิวเมนต์สุดท้ายคือจำนวนอาร์กิวเมนต์ที่เมธอด Ruby ต้องการ (ค่าลบหมายถึงอาร์กิวเมนต์ที่ไม่บังคับ)
rb_define_singleton_method
ฟังก์ชั่นใช้เพื่อกำหนดวิธีการเรียน
rb_define_singleton_method(rb_cHash, "[]", rb_hash_s_create, -1);
เนื้อหาของ rb_define_singleton_method
เป็นเพียงโค้ดบรรทัดเดียว:
rb_define_method(singleton_class_of(obj), ชื่อ, func, argc);
หากคุณต้องการสำรวจต่อ ไฟล์ที่ดีที่ควรดูคือ object.c
.
สำรวจห้องสมุดมาตรฐาน
โอเค วันนี้ C ก็เพียงพอแล้ว!
ลองอ่านโค้ด Ruby กันไหม
Ruby Standard Library เขียนด้วย Ruby และคุณสามารถค้นหาได้ภายใต้ /lib
ไดเรกทอรี
ไลบรารีมาตรฐานประกอบด้วยสิ่งต่างๆ เช่น OpenStruct, Base64
การเข้ารหัสและ Set
โครงสร้างข้อมูล
ชุดคล้ายกับอาร์เรย์ แต่มีคุณสมบัติพิเศษที่องค์ประกอบทั้งหมดไม่ซ้ำกัน กล่าวคือ ชุดไม่มีการซ้ำกัน
มันทำงานอย่างไร? มีอัลกอริธึมแฟนซีอยู่เบื้องหลังหรือไม่
ถ้าเราดูที่ set.rb
คุณจะค้นพบได้อย่างรวดเร็วว่าสิ่งนี้ได้รับการสนับสนุนโดย Hash
วัตถุ
# เพิ่มวัตถุที่กำหนดให้กับชุดและส่งคืนตัวเอง ใช้ +ผสาน+ เพื่อ# เพิ่มหลายองค์ประกอบพร้อมกัน def add(o) @hash[o] =selfendalias จริง <<เพิ่ม
ดังนั้น หากคุณเพิ่มองค์ประกอบที่ซ้ำกัน ไม่จำเป็นต้องตรวจสอบว่ามีองค์ประกอบนั้นอยู่แล้ว เพียงแค่เขียนทับองค์ประกอบเก่า
สำรวจรูบิเนียส
อีกวิธีหนึ่งในการสำรวจซอร์สโค้ดของ Ruby ก็คือการดูการใช้งานอื่นเช่น Rubinius
รหัส Rubinius มีการจัดระเบียบในลักษณะที่แตกต่างจาก MRI ดังนั้นสำหรับสิ่งนี้ ฉันชอบใช้ Github และคุณสมบัติ 'find file'
หากคุณต้องการเรียนรู้เพิ่มเติมเกี่ยวกับ Enumerable
จากนั้นคุณเพียงแค่พิมพ์ 'enumerable' และคุณจะเห็นไฟล์ที่เกี่ยวข้องทั้งหมด
บทสรุป
อย่างที่คุณเห็น คุณสามารถเรียนรู้วิธีที่ Ruby ทำสิ่งต่างๆ ภายใต้ประทุนโดยไม่ต้องใช้ความพยายามมากนัก ไปข้างหน้าและสำรวจด้วยตัวคุณเองและบอกให้ทุกคนรู้ว่าคุณค้นพบอะไร!
หากคุณชอบโพสต์นี้ อย่าลืมเข้าร่วมจดหมายข่าวของฉัน เพียงวางอีเมลของคุณในแบบฟอร์มด้านล่าง แล้วคุณจะได้รับการอัปเดตและเนื้อหาพิเศษฟรี