आप जानते होंगे कि Ruby कमांड-लाइन आर्गुमेंट्स को ARGV नामक एक ग्लोबल ऐरे में डालता है। लेकिन इसका नाम ARGV क्यों है? यह एक दिलचस्प इतिहास का पाठ है जो Ruby की C में जड़ों को उजागर करता है।
आर्गुमेंट वेक्टर
ARGV का मतलब है आर्गुमेंट वेक्टर। और इस अजीब पुराने ज़माने के उपयोग में "वेक्टर" का अर्थ है "एक-आयामी ऐरे"।
C में, हर प्रोग्राम का एक main() फंक्शन होता है। यह आमतौर पर ऐसा दिखता है:
int main(int argc, char *argv[]) {
... आपका कोड यहाँ
}
जैसा कि आपने शायद देखा, main फंक्शन के दो आर्गुमेंट्स होते हैं। ये क्रमशः एक काउंट और कमांड-लाइन आर्गुमेंट्स का एक ऐरे होते हैं।
जब आप bash को अपना प्रोग्राम चलाने के लिए कहते हैं, तो यह एक सिस्टम कॉल करता है जो OS को आपके प्रोग्राम के main फंक्शन को कॉल करने और कुछ argc और argv वैल्यूज़ पास करने का कारण बनता है।
Ruby
Ruby इंटरप्रेटर — कम से कम MRI — बस एक C प्रोग्राम है। यहाँ Ruby का main फंक्शन है:
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 इंटरप्रेटर के सभी ऑप्शन्स को हैंडल करता है और अंततः ruby_set_argv को कॉल करता है, जो आपके Ruby कोड में दिखने वाले 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 कोडबेस में गोता लगाने में नया हूँ, लेकिन अंदर जाकर यह देखना मजेदार है कि चीज़ें वास्तव में कैसे काम करती हैं।