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

Deep Dive: สำรวจ Ruby MRI Source Code

ถ้าใช้ Ruby มานาน อาจสงสัยว่าบางอย่างทำงานภายในอย่างไร วิธีลึกเข้าไปคืออ่าน source code ที่ทำให้มันทำงาน แม้ไม่รู้ C ก็ยังเรียนรู้ได้บ้าง

Source code อยู่ที่ github repo ของ Ruby แนะนำใช้ tool เช่น Codequery ช่วยหา class และ method names ง่ายขึ้น

สำรวจ Core Classes

ส่วนใหญ่จะอยู่ใน root folder นั่นคือที่ source code ของ core classes ทั้งหมด เช่น Object ใน object.c หรือ Array ใน array.c

มาดู hash.c scroll ลงไป line 4468 จะเจอชื่อที่คุ้นเคย

เริ่มจากนี้:

rb_cHash = rb_define_class("Hash", rb_cObject);

บรรทัดนี้ define class Hash ด้วย function rb_define_class argument ที่ 2 (rb_cObject) คือ superclass

อยากรู้การ define class ทำงานอย่างไร ค้นหา rb_define_class

Deep Dive: สำรวจ Ruby MRI Source Code

ส่วนแรกของ rb_define_class เช็คว่า class define แล้วหรือยัง

if (rb_const_defined(rb_cObject, id)) {
  // ...
}

ใน if block Ruby ทำ sanity checks เช่นเช็คว่า class ที่ทำงานอยู่ defined แล้ว ถ้ายังไม่ define จะ define แบบนี้:

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);
return klass;

อ่าน definition ทุกเมธอดได้ แต่คิดว่า self-explanatory แล้ว ใน st_add_direct 'st' หมายถึง 'symbol table' ซึ่งก็คือ hash table rb_const_set set constant บน class Object ทำให้ class ใช้ได้ทุกที่ rb_class_inherited เรียกเมธอด inherited ของ superclass

ส่วนต่อไปคือ method definitions 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, 0);
rb_define_method(rb_cHash,"empty?", rb_hash_empty_p, 0);

Arguments:

  • Arg 1: class ที่ define เมธอดนี้
  • Arg 2: method name
  • Arg 3: C function ที่ implement เมธอดจริง
  • Arg 4: จำนวน arguments ที่ Ruby method ต้องการ (ค่าลบ = optional arguments)

rb_define_singleton_method ใช้ define class method:

rb_define_singleton_method(rb_cHash, "[]", rb_hash_s_create, -1);

Body ของ rb_define_singleton_method แค่บรรทัดเดียว:

rb_define_method(singleton_class_of(obj), name, func, argc);

อยากสำรวจต่อ ไฟล์ object.c ดีนะ

สำรวจ Standard Library

พอ C แล้ววันนี้! ลองอ่าน Ruby code ดีกว่า Standard Library เขียนด้วย Ruby อยู่ใน /lib directory มี OpenStruct, Base64 encoding, Set data structure

Set คล้าย array แต่ทุก elements unique ไม่มี duplicates ทำงานอย่างไร? มี algorithms แฟนซีไหม?

ดู set.rb จะพบว่า backed by Hash object:

# Adds the given object to the set and returns self. Use +merge+ to
# add many elements at once.
def add(o)
  @hash[o] = true
  self
end
alias << add

ถ้า add duplicated element ไม่ต้องเช็คว่ามีอยู่แล้ว จะ overwrite เก่าไปเลย

สำรวจ Rubinius

อีกวิธีสำรวจ Ruby source code: ดู alternate implementations เช่น Rubinius โค้ดจัดระเบียบต่าง MRI ชอบใช้ Github และ 'find file' feature

Deep Dive: สำรวจ Ruby MRI Source Code

อยากเรียนรู้ Enumerable มากกว่านี้ แค่พิมพ์ 'enumerable' จะเจอไฟล์เกี่ยวข้องทั้งหมด

สรุป

เห็นได้ว่าสามารถเรียนรู้ Ruby ภายในได้โดยไม่ยาก ลองสำรวจเองและบอกทุกคนว่าคุณค้นพบอะไร!

ชอบโพสต์นี้ อย่าลืมสมัคร newsletter ใส่ email ในฟอร์มด้านล่าง รับ updates ฟรีและ exclusive content