স্ট্যান্ডার্ড আউটপুটের পরিবর্তে স্ট্যান্ডার্ড এররে (Standard Error) এরর মেসেজ লেখা
এই মুহূর্তে, আমরা println!
ম্যাক্রো ব্যবহার করে আমাদের সমস্ত আউটপুট টার্মিনালে লিখছি। বেশিরভাগ টার্মিনালে দুই ধরনের আউটপুট থাকে: সাধারণ তথ্যের জন্য স্ট্যান্ডার্ড আউটপুট (stdout
) এবং এরর মেসেজের জন্য স্ট্যান্ডার্ড এরর (stderr
)। এই পার্থক্য ব্যবহারকারীদের একটি প্রোগ্রামের সফল আউটপুটকে একটি ফাইলে পাঠানোর সুযোগ দেয়, কিন্তু তারপরেও এরর মেসেজগুলো স্ক্রিনে প্রিন্ট করতে পারে।
println!
ম্যাক্রো শুধুমাত্র স্ট্যান্ডার্ড আউটপুটে প্রিন্ট করতে সক্ষম, তাই স্ট্যান্ডার্ড এররে প্রিন্ট করার জন্য আমাদের অন্য কিছু ব্যবহার করতে হবে।
এররগুলো কোথায় লেখা হচ্ছে তা পরীক্ষা করা
প্রথমে চলুন দেখি minigrep
দ্বারা প্রিন্ট করা কন্টেন্ট বর্তমানে কীভাবে স্ট্যান্ডার্ড আউটপুটে লেখা হচ্ছে, যার মধ্যে সেইসব এরর মেসেজও অন্তর্ভুক্ত যা আমরা স্ট্যান্ডার্ড এররে লিখতে চাই। আমরা ইচ্ছাকৃতভাবে একটি এরর ঘটিয়ে স্ট্যান্ডার্ড আউটপুট স্ট্রিমকে একটি ফাইলে রিডাইরেক্ট করে এটি করব। আমরা স্ট্যান্ডার্ড এরর স্ট্রিম রিডাইরেক্ট করব না, তাই স্ট্যান্ডার্ড এররে পাঠানো যেকোনো কন্টেন্ট স্ক্রিনে প্রদর্শিত হতে থাকবে।
কমান্ড লাইন প্রোগ্রামগুলো থেকে আশা করা হয় যে তারা এরর মেসেজ স্ট্যান্ডার্ড এরর স্ট্রিমে পাঠাবে যাতে আমরা স্ট্যান্ডার্ড আউটপুট স্ট্রিম একটি ফাইলে রিডাইরেক্ট করলেও স্ক্রিনে এরর মেসেজ দেখতে পাই। আমাদের প্রোগ্রাম বর্তমানে সঠিকভাবে আচরণ করছে না: আমরা দেখতে চলেছি যে এটি এরর মেসেজ আউটপুট একটি ফাইলে সংরক্ষণ করছে!
এই আচরণটি দেখানোর জন্য, আমরা প্রোগ্রামটি >
এবং ফাইলের পাথ, output.txt দিয়ে চালাব, যেখানে আমরা স্ট্যান্ডার্ড আউটপুট স্ট্রিম রিডাইরেক্ট করতে চাই। আমরা কোনো আর্গুমেন্ট পাস করব না, যা একটি এরর তৈরি করবে:
$ cargo run > output.txt
>
সিনট্যাক্সটি শেলকে বলে স্ট্যান্ডার্ড আউটপুটের কন্টেন্ট স্ক্রিনের পরিবর্তে output.txt-এ লিখতে। আমরা স্ক্রিনে প্রত্যাশিত এরর মেসেজটি দেখতে পাইনি, তার মানে এটি অবশ্যই ফাইলে চলে গেছে। output.txt ফাইলে এটি রয়েছে:
Problem parsing arguments: not enough arguments
হ্যাঁ, আমাদের এরর মেসেজটি স্ট্যান্ডার্ড আউটপুটে প্রিন্ট হচ্ছে। এই ধরনের এরর মেসেজ স্ট্যান্ডার্ড এররে প্রিন্ট করা অনেক বেশি দরকারী যাতে শুধুমাত্র একটি সফল রানের ডেটা ফাইলে শেষ হয়। আমরা এটি পরিবর্তন করব।
স্ট্যান্ডার্ড এররে এরর প্রিন্ট করা
এরর মেসেজগুলো কীভাবে প্রিন্ট করা হয় তা পরিবর্তন করার জন্য আমরা লিস্টিং ১২-২৪-এর কোড ব্যবহার করব। এই অধ্যায়ের শুরুতে আমরা যে রিফ্যাক্টরিং করেছি তার কারণে, এরর মেসেজ প্রিন্ট করা সমস্ত কোড একটি ফাংশন, main
-এর মধ্যে রয়েছে। স্ট্যান্ডার্ড লাইব্রেরি eprintln!
ম্যাক্রো সরবরাহ করে যা স্ট্যান্ডার্ড এরর স্ট্রিমে প্রিন্ট করে, তাই আসুন আমরা যে দুটি জায়গায় এরর প্রিন্ট করার জন্য println!
কল করছিলাম, সেখানে eprintln!
ব্যবহার করি।
use std::env;
use std::error::Error;
use std::fs;
use std::process;
use minigrep::{search, search_case_insensitive};
fn main() {
let args: Vec<String> = env::args().collect();
let config = Config::build(&args).unwrap_or_else(|err| {
eprintln!("Problem parsing arguments: {err}");
process::exit(1);
});
if let Err(e) = run(config) {
eprintln!("Application error: {e}");
process::exit(1);
}
}
pub struct Config {
pub query: String,
pub file_path: String,
pub ignore_case: bool,
}
impl Config {
fn build(args: &[String]) -> Result<Config, &'static str> {
if args.len() < 3 {
return Err("not enough arguments");
}
let query = args[1].clone();
let file_path = args[2].clone();
let ignore_case = env::var("IGNORE_CASE").is_ok();
Ok(Config {
query,
file_path,
ignore_case,
})
}
}
fn run(config: Config) -> Result<(), Box<dyn Error>> {
let contents = fs::read_to_string(config.file_path)?;
let results = if config.ignore_case {
search_case_insensitive(&config.query, &contents)
} else {
search(&config.query, &contents)
};
for line in results {
println!("{line}");
}
Ok(())
}
আসুন এখন প্রোগ্রামটি আবার একইভাবে চালাই, কোনো আর্গুমেন্ট ছাড়াই এবং >
দিয়ে স্ট্যান্ডার্ড আউটপুট রিডাইরেক্ট করে:
$ cargo run > output.txt
Problem parsing arguments: not enough arguments
এখন আমরা স্ক্রিনে এররটি দেখতে পাচ্ছি এবং output.txt ফাইলে কিছুই নেই, যা কমান্ড লাইন প্রোগ্রাম থেকে আমরা আশা করি।
আসুন প্রোগ্রামটি আবার এমন আর্গুমেন্ট দিয়ে চালাই যা কোনো এরর তৈরি করে না কিন্তু স্ট্যান্ডার্ড আউটপুট একটি ফাইলে রিডাইরেক্ট করে, যেমন:
$ cargo run -- to poem.txt > output.txt
আমরা টার্মিনালে কোনো আউটপুট দেখতে পাব না, এবং output.txt আমাদের ফলাফল ধারণ করবে:
ফাইলের নাম: output.txt
Are you nobody, too?
How dreary to be somebody!
এটি প্রমাণ করে যে আমরা এখন সফল আউটপুটের জন্য স্ট্যান্ডার্ড আউটপুট এবং এরর আউটপুটের জন্য যথাযথভাবে স্ট্যান্ডার্ড এরর ব্যবহার করছি।
সারসংক্ষেপ
এই অধ্যায়ে আমরা এ পর্যন্ত শেখা প্রধান কিছু ধারণা পুনরালোচনা করেছি এবং রাস্ট-এ সাধারণ I/O অপারেশনগুলো কীভাবে করতে হয় তা কভার করেছি। কমান্ড লাইন আর্গুমেন্ট, ফাইল, এনভায়রনমেন্ট ভেরিয়েবল, এবং এরর প্রিন্ট করার জন্য eprintln!
ম্যাক্রো ব্যবহার করে, আপনি এখন কমান্ড লাইন অ্যাপ্লিকেশন লেখার জন্য প্রস্তুত। পূর্ববর্তী অধ্যায়গুলোর ধারণার সাথে মিলিত হয়ে, আপনার কোড সুসংগঠিত হবে, উপযুক্ত ডেটা স্ট্রাকচারে কার্যকরভাবে ডেটা সংরক্ষণ করবে, সুন্দরভাবে এরর হ্যান্ডেল করবে এবং ভালোভাবে টেস্ট করা থাকবে।
এরপরে, আমরা ফাংশনাল ল্যাঙ্গুয়েজ দ্বারা প্রভাবিত রাস্টের কিছু ফিচার অন্বেষণ করব: ক্লোজার এবং ইটারেটর।