আপনি জানতে পারেন Ruby কমান্ড-লাইন আর্গুমেন্টগুলো একটি গ্লোবাল অ্যারে olan ARGV-এ রাখে। কিন্তু এটিকে ARGV কেন বলা হয়? এটি একটি रोचক ইতিহাসের পাঠ যা Ruby-এর C-তে উৎপত্তি হাইলাইট করে।
আর্গুমেন্ট ভেক্টর
ARGV হল Argument Vector-এর সংক্ষিপ্ত রূপ। এবং এই প্রাচীন ব্যবহারে "ভেক্টর" বলতে এক-মাত্রিক অ্যারে-কে বোঝানো হয়।
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 কোডবেসে ডুব মুহুর্তে নতুন, কিন্তু এতে ঢুকে দেখতে খুব মজা লাগে যে জিনিসগুলো কীভাবে কাজ করে।