স্কোপ এবং প্রাইভেসি নিয়ন্ত্রণের জন্য মডিউল ডিফাইন করা
এই বিভাগে, আমরা মডিউল এবং মডিউল সিস্টেমের অন্যান্য অংশ নিয়ে কথা বলব, যেমন পাথ (paths), যা আপনাকে বিভিন্ন আইটেমের নামকরণ করতে দেয়; use
কীওয়ার্ড, যা একটি পাথকে স্কোপের মধ্যে নিয়ে আসে; এবং pub
কীওয়ার্ড, যা আইটেমগুলোকে পাবলিক করে। আমরা as
কীওয়ার্ড, এক্সটার্নাল প্যাকেজ এবং গ্লোব অপারেটর নিয়েও আলোচনা করব।
মডিউল চিট শিট
আমরা মডিউল এবং পাথের বিস্তারিত বিবরণে যাওয়ার আগে, এখানে মডিউল, পাথ, use
কীওয়ার্ড, এবং pub
কীওয়ার্ড কম্পাইলারে কীভাবে কাজ করে এবং বেশিরভাগ ডেভেলপাররা কীভাবে তাদের কোড অর্গানাইজ করেন তার একটি দ্রুত রেফারেন্স দেওয়া হলো। আমরা এই অধ্যায় জুড়ে এই নিয়মগুলির প্রতিটি উদাহরণ নিয়ে আলোচনা করব, কিন্তু মডিউল কীভাবে কাজ করে তা মনে করিয়ে দেওয়ার জন্য এটি একটি চমৎকার রেফারেন্স।
- ক্রেট রুট থেকে শুরু করুন: একটি ক্রেট কম্পাইল করার সময়, কম্পাইলার প্রথমে ক্রেট রুট ফাইলে (সাধারণত একটি লাইব্রেরি ক্রেটের জন্য src/lib.rs বা একটি বাইনারি ক্রেটের জন্য src/main.rs) কম্পাইল করার জন্য কোড খোঁজে।
- মডিউল ডিক্লেয়ার করা: ক্রেট রুট ফাইলে, আপনি নতুন মডিউল ডিক্লেয়ার করতে পারেন; ধরুন আপনি
mod garden;
দিয়ে একটি “garden” মডিউল ডিক্লেয়ার করলেন। কম্পাইলার মডিউলের কোডটি এই জায়গাগুলিতে খুঁজবে:- ইনলাইন,
mod garden
-এর পরের সেমিকোলনটির পরিবর্তে কোঁকড়া বন্ধনীর (curly brackets) ভিতরে। - src/garden.rs ফাইলে।
- src/garden/mod.rs ফাইলে।
- ইনলাইন,
- সাবমডিউল ডিক্লেয়ার করা: ক্রেট রুট ছাড়া অন্য যেকোনো ফাইলে আপনি সাবমডিউল ডিক্লেয়ার করতে পারেন। উদাহরণস্বরূপ, আপনি হয়তো src/garden.rs ফাইলে
mod vegetables;
ডিক্লেয়ার করতে পারেন। কম্পাইলার সাবমডিউলের কোডটি প্যারেন্ট মডিউলের নামের ডিরেক্টরিতে এই জায়গাগুলিতে খুঁজবে:- ইনলাইন, সরাসরি
mod vegetables
-এর পরে, সেমিকোলনের পরিবর্তে কোঁকড়া বন্ধনীর ভিতরে। - src/garden/vegetables.rs ফাইলে।
- src/garden/vegetables/mod.rs ফাইলে।
- ইনলাইন, সরাসরি
- মডিউলের কোডের পাথ: একবার একটি মডিউল আপনার ক্রেটের অংশ হয়ে গেলে, আপনি সেই ক্রেটের অন্য যেকোনো জায়গা থেকে সেই মডিউলের কোড রেফার করতে পারবেন, যতক্ষণ প্রাইভেসি নিয়ম অনুমতি দেয়, কোডের পাথ ব্যবহার করে। উদাহরণস্বরূপ, garden vegetables মডিউলের একটি
Asparagus
টাইপcrate::garden::vegetables::Asparagus
পাথে পাওয়া যাবে। - প্রাইভেট বনাম পাবলিক: একটি মডিউলের ভিতরের কোড ডিফল্টরূপে তার প্যারেন্ট মডিউল থেকে প্রাইভেট থাকে। একটি মডিউলকে পাবলিক করতে,
mod
-এর পরিবর্তেpub mod
দিয়ে ডিক্লেয়ার করুন। একটি পাবলিক মডিউলের ভেতরের আইটেমগুলোকেও পাবলিক করতে, তাদের ডিক্লেয়ারেশনের আগেpub
ব্যবহার করুন। use
কীওয়ার্ড: একটি স্কোপের মধ্যে,use
কীওয়ার্ড লম্বা পাথের পুনরাবৃত্তি কমাতে আইটেমগুলোর জন্য শর্টকাট তৈরি করে। যেকোনো স্কোপে যেখানেcrate::garden::vegetables::Asparagus
রেফার করা যায়, আপনিuse crate::garden::vegetables::Asparagus;
ব্যবহার করে একটি শর্টকাট তৈরি করতে পারেন এবং তারপর থেকে সেই স্কোপে ঐ টাইপটি ব্যবহার করার জন্য আপনাকে কেবলAsparagus
লিখতে হবে।
এখানে, আমরা backyard
নামে একটি বাইনারি ক্রেট তৈরি করছি যা এই নিয়মগুলি তুলে ধরে। ক্রেটের ডিরেক্টরি, যার নামও backyard
, তাতে এই ফাইল এবং ডিরেক্টরিগুলো রয়েছে:
backyard
├── Cargo.lock
├── Cargo.toml
└── src
├── garden
│ └── vegetables.rs
├── garden.rs
└── main.rs
এই ক্ষেত্রে ক্রেট রুট ফাইলটি হলো src/main.rs, এবং এতে রয়েছে:
use crate::garden::vegetables::Asparagus;
pub mod garden;
fn main() {
let plant = Asparagus {};
println!("I'm growing {plant:?}!");
}
pub mod garden;
লাইনটি কম্পাইলারকে src/garden.rs-এ পাওয়া কোড অন্তর্ভুক্ত করতে বলে, যা হলো:
pub mod vegetables;
এখানে, pub mod vegetables;
মানে src/garden/vegetables.rs-এর কোডও অন্তর্ভুক্ত করা হয়েছে। সেই কোডটি হলো:
#[derive(Debug)]
pub struct Asparagus {}
এখন আসুন এই নিয়মগুলির বিস্তারিত বিবরণে যাই এবং সেগুলি বাস্তবে প্রদর্শন করি!
সম্পর্কিত কোডকে মডিউলে গ্রুপিং করা
মডিউল (Modules) আমাদের একটি ক্রেটের মধ্যে পঠনযোগ্যতা (readability) এবং সহজ পুনঃব্যবহারের জন্য কোড অর্গানাইজ করতে দেয়। মডিউল আমাদের আইটেমগুলির প্রাইভেসি (privacy) নিয়ন্ত্রণ করার অনুমতিও দেয় কারণ একটি মডিউলের ভেতরের কোড ডিফল্টরূপে প্রাইভেট থাকে। প্রাইভেট আইটেমগুলো হলো অভ্যন্তরীণ ইমপ্লিমেন্টেশন ডিটেইলস যা বাইরের ব্যবহারের জন্য উপলব্ধ নয়। আমরা মডিউল এবং তার ভেতরের আইটেমগুলোকে পাবলিক করার সিদ্ধান্ত নিতে পারি, যা সেগুলোকে এক্সপোজ করে এবং বাইরের কোডকে সেগুলো ব্যবহার ও তার উপর নির্ভর করার অনুমতি দেয়।
একটি উদাহরণ হিসাবে, চলুন একটি লাইব্রেরি ক্রেট লিখি যা একটি রেস্তোরাঁর কার্যকারিতা প্রদান করে। আমরা ফাংশনের সিগনেচারগুলো ডিফাইন করব কিন্তু তাদের বডি খালি রাখব, যাতে একটি রেস্তোরাঁর ইমপ্লিমেন্টেশনের পরিবর্তে কোডের অর্গানাইজেশনের উপর মনোযোগ দিতে পারি।
রেস্তোরাঁ শিল্পে, একটি রেস্তোরাঁর কিছু অংশকে ফ্রন্ট অফ হাউস (front of house) এবং অন্যগুলোকে ব্যাক অফ হাউস (back of house) বলা হয়। ফ্রন্ট অফ হাউস হলো যেখানে গ্রাহকরা থাকেন; এর মধ্যে রয়েছে যেখানে হোস্টরা গ্রাহকদের বসান, সার্ভাররা অর্ডার এবং পেমেন্ট নেন, এবং বারটেন্ডাররা ড্রিঙ্ক তৈরি করেন। ব্যাক অফ হাউস হলো যেখানে শেফ এবং বাবুর্চিরা রান্নাঘরে কাজ করেন, ডিশওয়াশাররা থালাবাসন পরিষ্কার করেন, এবং ম্যানেজাররা প্রশাসনিক কাজ করেন।
আমাদের ক্রেটকে এইভাবে গঠন করার জন্য, আমরা এর ফাংশনগুলোকে নেস্টেড মডিউলে অর্গানাইজ করতে পারি। cargo new restaurant --lib
চালিয়ে restaurant
নামে একটি নতুন লাইব্রেরি তৈরি করুন। তারপর কিছু মডিউল এবং ফাংশন সিগনেচার ডিফাইন করতে Listing 7-1-এর কোডটি src/lib.rs-এ লিখুন; এই কোডটি হলো ফ্রন্ট অফ হাউস সেকশন।
mod front_of_house {
mod hosting {
fn add_to_waitlist() {}
fn seat_at_table() {}
}
mod serving {
fn take_order() {}
fn serve_order() {}
fn take_payment() {}
}
}
আমরা mod
কীওয়ার্ড এবং তারপরে মডিউলের নাম (এই ক্ষেত্রে, front_of_house
) দিয়ে একটি মডিউল ডিফাইন করি। মডিউলের বডি তখন কোঁকড়া বন্ধনীর ভিতরে যায়। মডিউলের ভিতরে, আমরা অন্য মডিউল রাখতে পারি, যেমন এই ক্ষেত্রে hosting
এবং serving
মডিউল। মডিউল অন্যান্য আইটেম, যেমন struct, enum, constant, trait এবং Listing 7-1-এর মতো ফাংশনের ডেফিনিশনও রাখতে পারে।
মডিউল ব্যবহার করে, আমরা সম্পর্কিত ডেফিনিশনগুলোকে একসাথে গ্রুপ করতে পারি এবং কেন তারা সম্পর্কিত তার নামকরণ করতে পারি। এই কোড ব্যবহারকারী প্রোগ্রামাররা সমস্ত ডেফিনিশন পড়ার পরিবর্তে গ্রুপগুলোর উপর ভিত্তি করে কোড নেভিগেট করতে পারবেন, যা তাদের জন্য প্রাসঙ্গিক ডেফিনিশন খুঁজে পাওয়া সহজ করে তোলে। যে প্রোগ্রামাররা এই কোডে নতুন ফাংশনালিটি যোগ করবেন, তারা জানবেন প্রোগ্রামকে অর্গানাইজড রাখতে কোডটি কোথায় রাখতে হবে।
পূর্বে, আমরা উল্লেখ করেছি যে src/main.rs এবং src/lib.rs-কে ক্রেট রুট বলা হয়। তাদের এই নামের কারণ হলো এই দুটি ফাইলের বিষয়বস্তু ক্রেটের মডিউল স্ট্রাকচারের রুটে crate
নামে একটি মডিউল তৈরি করে, যা মডিউল ট্রি (module tree) নামে পরিচিত।
Listing 7-2, Listing 7-1-এর স্ট্রাকচারের জন্য মডিউল ট্রি দেখায়।
crate
└── front_of_house
├── hosting
│ ├── add_to_waitlist
│ └── seat_at_table
└── serving
├── take_order
├── serve_order
└── take_payment
এই ট্রি দেখায় কিভাবে কিছু মডিউল অন্য মডিউলের ভিতরে নেস্ট করা আছে; উদাহরণস্বরূপ, hosting
front_of_house
-এর ভিতরে নেস্ট করা। ট্রি এটিও দেখায় যে কিছু মডিউল সিবলিং (siblings), যার মানে তারা একই মডিউলে ডিফাইন করা হয়েছে; hosting
এবং serving
হলো front_of_house
-এর মধ্যে ডিফাইন করা সিবলিং। যদি মডিউল A মডিউল B-এর ভিতরে থাকে, আমরা বলি যে মডিউল A হলো মডিউল B-এর চাইল্ড (child) এবং মডিউল B হলো মডিউল A-এর প্যারেন্ট (parent)। লক্ষ্য করুন যে পুরো মডিউল ট্রি-টি crate
নামের একটি অন্তর্নিহিত (implicit) মডিউলের অধীনে রুট করা হয়েছে।
মডিউল ট্রি আপনাকে আপনার কম্পিউটারের ফাইলসিস্টেমের ডিরেক্টরি ট্রি-এর কথা মনে করিয়ে দিতে পারে; এটি একটি খুব উপযুক্ত তুলনা! ফাইলসিস্টেমের ডিরেক্টরির মতো, আপনি আপনার কোড অর্গানাইজ করতে মডিউল ব্যবহার করেন। এবং একটি ডিরেক্টরিতে ফাইলের মতো, আমাদের মডিউলগুলো খুঁজে বের করার একটি উপায় প্রয়োজন।