คุณอาจรู้ว่า Ruby ติดอาร์กิวเมนต์บรรทัดคำสั่งในอาร์เรย์ส่วนกลางที่เรียกว่า ARGV แต่ทำไมถึงเรียกว่า ARGV? เป็นบทเรียนประวัติศาสตร์ที่น่าสนใจที่เน้นย้ำถึงที่มาของ Ruby ในภาษา C
เวกเตอร์อาร์กิวเมนต์
ARGV ย่อมาจากเวกเตอร์อาร์กิวเมนต์ และ "เวกเตอร์" ในการใช้งานสมัยเก่าที่แปลกประหลาดนี้หมายถึง "อาร์เรย์หนึ่งมิติ"
ใน C ทุกโปรแกรมมี main()
การทำงาน. โดยทั่วไปจะมีลักษณะดังนี้:
int main(int argc, char *argv[]) {
... your code here
}
อย่างที่คุณอาจสังเกตเห็น ฟังก์ชันหลักมีสองอาร์กิวเมนต์ สิ่งเหล่านี้คือการนับและอาร์เรย์ของอาร์กิวเมนต์บรรทัดคำสั่งตามลำดับ
เมื่อคุณบอกให้ bash รันโปรแกรม ระบบจะทำการเรียกซึ่งทำให้ OS เรียก main
ของโปรแกรมของคุณ และส่งผ่าน argc
. บางอย่าง และ argv
ค่า
ทับทิม
ล่าม Ruby - อย่างน้อย MRI - เป็นเพียงโปรแกรม C นี่คือ main
. ของ Ruby ฟังก์ชัน:
int
main(int argc, char **argv)
{
#ifdef RUBY_DEBUG_ENV
ruby_set_debug_option(getenv("RUBY_DEBUG"));
#endif
#ifdef HAVE_LOCALE_H
setlocale(LC_CTYPE, "");
#endif
ruby_sysinit(&argc, &argv);
{
RUBY_INIT_STACK;
ruby_init();
return ruby_run_node(ruby_options(argc, argv));
}
}
อย่างที่คุณเห็น มันส่งผ่าน argc
และ argv
ไปยังฟังก์ชันที่เรียกว่า ruby_options
ซึ่งจะเรียก ruby_process_options
ซึ่งเรียก process_options
.
ที่จัดการตัวเลือกล่ามทับทิมทั้งหมดและในที่สุดก็เรียก ruby_set_argv
ซึ่งตั้งค่า ARGV
คุณเห็นในรหัสทับทิมของคุณ
void
ruby_set_argv(int argc, char **argv)
{
int i;
VALUE av = rb_argv;
#if defined(USE_DLN_A_OUT)
if (origarg.argv)
dln_argv0 = origarg.argv[0];
else
dln_argv0 = argv[0];
#endif
rb_ary_clear(av);
for (i = 0; i < argc; i++) {
VALUE arg = external_str_new_cstr(argv[i]);
OBJ_FREEZE(arg);
rb_ary_push(av, arg);
}
}
ค่อนข้างเรียบร้อย ฉันยังใหม่จริงๆ ในการดำดิ่งสู่ MRI codebase แต่การกระโดดเข้าไปและดูว่าสิ่งต่าง ๆ ทำงานอย่างไรนั้นสนุกดี