কম্পিউটার টিউটোরিয়াল

গ্রেসফুল এক্সিট: রুবি প্রোগ্রাম টার্মিনেট করার সেরা অনুশীলন

ডেভেলপাররা প্রোগ্রাম চালাতে इतना সময় ব্যয় করি যে সহজে ভুলে যাই কীভাবে সেগুলো এক্সিট করে। এবং এটি গুরুত্বপূর্ণ! যখন আপনার প্রোগ্রামগুলো এক্সিট করার সময় সঠিকভাবে behave করে, তবে সেগুলো পরিচালনা করা অনেক সহজ হয় এবং সেগুলো стандарт devops টুলসের সাথে কাজ করার সম্ভাবনা বেশি হয়।

একটি রুবি প্রোগ্রাম এক্সিট করার অনেক উপায় আছে। আমি 그중 কিছু নিচে দেখিয়েছি। এই পোস্টে আমরা প্রতিটি বিষয়ের ডিটেইলস এবং কীভাবে সেগুলো ব্যবহার করে আপনার অ্যাপকে একটি ভালো-मানের ইউনিক্স সিটিজেন বানাতে হয় তা আলোচনা করব।

# আপনি মেথড কল করে এক্সিট করতে পারেন
exit
exit!
abort("She cannot take any more of this, Captain!")
# ...অথবা এক্সেপশন ক্যাচ না করলে
raise("Destroyed...")
fail
# ...অথবা প্রোগ্রামটি স্বাভাবিকভাবে শেষ হওয়া দিন। :)

এক্সিট কোড, এবং আপনি

লিনাক্স এবং OSX-এ রান হওয়া প্রতিটি প্রোগ্রাম শেষ হলে একটি এক্সিট স্ট্যাটাস কোড রিটার্ন করে। আপনি সাধারণত এক্সিট কোড দেখেন না। এটি OS পেছনের দরজায় ব্যবহার করে নির্ধারণ করে যে প্রোগ্রামটি স্বাভাবিকভাবে এক্সিট করেছে কিনা অথবা কোনো এরর হয়েছিল কিনা।

আপনি যদি bash ব্যবহার করেন, তবে আপনি য نشرت প্রোগ্রামের এক্সিট কোড দেখতে পারেন $? এনভায়রনমেন্ট ভেরিয়েবল পরীক্ষা করে। নিচের উদাহরণে একটি ফেইলার এবং তারপর একটি সাক্সেসের এক্সিট কোড দেখানো হয়েছে।

% ls this-file-doesnt-exist
ls: this-file-doesnt-exist: No such file or directory
blog% echo $?
1
% ls .
bm.rb
% echo $?
0

সাধারণত, ইউনিক্স-ভিত্তিক সিস্টেমের জন্য নিয়ম হলো শূন্য মানে সাক্সেস। নন-জিরো মানে ফেইলার।

আপনি যদি কখনো bash-এ && "অপারেটর" ব্যবহার করে থাকেন, তবে আপনি স্ট্যাটাস কোড ব্যবহার করেছেন। নিচের উদাহরণে, আমরা bash-কে বলছি প্রোগ্রাম B রান করবে শুধু যদি প্রোগ্রাম A সফল হয়।

% a && b

আপনি এই ট্রিকটি অনেকভাবে ব্যবহার করতে পারেন। উদাহরণস্বরূপ, আপনি অ্যাসেট প্রি-কম্পাইল করতে চাইতে পারেন, এবং সেগুলো CDN-এ আপলোড করতে চাইতে পারেন।

blog% rake assets:precompile && rake cdn:upload_assets

রুবিতে এক্সিট স্ট্যাটাস নির্দিষ্ট করা

রুবি আমাদের জন্য এক্সিট স্ট্যাটাস বিষয়ক অনেক কিছু হ্যান্ডেল করে। যদি আপনার প্রোগ্রাম স্বাভাবিকভাবে এক্সিট করে, তবে এটি একটি "সাক্সেস" স্ট্যাটাস রিটার্ন করে। যদি এটি অনকaught এক্সেপশনের কারণে ফেইল করে, তবে এটি একটি "ফেইলার" স্ট্যাটাস দেয়। নিচে আমি একটি স্ক্রিপ্টের এক্সিট কোড দেখাচ্ছি যেটি একটি এক্সেপশন রেইজ করেছিল।

% ruby err.rb
err.rb:1:in `
': goodbye (RuntimeError) tmp% echo $? 1

কিন্তু যদি আপনি কোনো অনকaught এক্সেপশন না চান? যদি আপনি ক্লিনলি এক্সিট করতে চান, কিন্তু এখনও একটি "ফেইলড" এরর কোড রিটার্ন করতে চান? আরও, যদি আপনি একটি কাস্টম কোড একটি এরর মেসেজের সাথে রিটার্ন করতে চান?

সৌভাগ্য থেকে, এটি খুব সহজ। শুধু exit ফাংশনে একটি আর্গুমেন্ট পাস করুন। আর্গুমেন্টটি একটি বুলিয়ান বা ইন্টিজার হতে পারে। যদি এটি বুলিয়ান হয়, তবে true মানে সাক্সেস। যদি এটি ইন্টিজার হয় তবে 0 মানে সাক্সেস।

exit(true)   # "সাক্সেস" কোড দিয়ে এক্সিট
exit(0)      # "সাক্সেস" কোড দিয়ে এক্সিট
exit(false)  # "ফেইলার" কোড দিয়ে এক্সিট
exit(1)      # "ফেইলার" কোড দিয়ে এক্সিট
exit(436)    # কাস্টম ফেইলার এরর কোড

exit কিভাবে কাজ করে হুডের নিচে

exit মেথড সাধারনভাবে একটি SystemExit এক্সেপশন রেইজ করে। যদি এটি অনকaught থাকে, তবে প্রোগ্রাম অবোর্ট হয় যেকোনো অন্য অনকaught এক্সেপশনের মত। এটি খুব কুল, কিন্তু এর কিছু আকর্ষণীয় ফলাফল আছে।

যদি আপনি সকল SystemExit এক্সেপশন নিঘল দেন, তবে আপনি exit মেথড ভাঙে দেবেন। আমি নিচের উদাহরণে এটি দেখিয়েছি।

begin
  exit 100
rescue SystemExit => e
  puts "Tried to exit with status #{ e.status }"
end
puts "...but it never exited, because we swallowed the exception"
# আউটপুট:
# Tried to exit with status 100
# ...but it never exited, because we swallowed the exception

এটি এখনো একটি কারণ যে কখনো Exception রescu করা উচিত নয়। কারণ SystemExit Exception-এর থেকে ইনহেরিট করে, Exception নিঘলে exit ভাঙে যাবে।

begin
  exit
rescue Exception # কখনোই এটি করবেন না
  puts "I just broke the exit function!"
end

মানব-পাঠযোগ্য এরর মেসেজ

যদিও এক্সিট কোড মেশিনের জন্য চমৎকার, আমরা মানুষ প্রায়শই কিছু ব্যাখ্যামূলক টেক্সট পছন্দ করি। সৌভাগ্য থেকে, OS আমাদের একটি আউটপুট স্ট্রিম দেয় এরর মেসেজের মতো জিনিসপত্রের জন্য। হ্যাঁ, আমি STDERR-র কথা বলছি।

আপনি STDERR-এ লিখতে পারেন যেকোনো IO অবজেক্টের মত। নিচের উদাহরণে আমি একটি এরর মেসেজ লিখছি এবং একটি "এরর" স্ট্যাটাসের সাথে এক্সিট করছি।

STDERR.puts("ABORTED! You forgot to BAR the BAZ")
exit(false)

এটি রুবি হলেও, STDERR-এ লিখে এরর কোডের সাথে এক্সিট করার একটি সংক্ষিপ্ত উপায় আছে। শুধু abort মেথড ব্যবহার করুন।

# মেসেজটি STDERR-এ লিখুন এবং একটি এরর স্ট্যাটাস কোডের সাথে এক্সিট করুন
abort("ABORTED! You forgot to BAR the BAZ")

at_exit মাধ্যমে কলব্যাক

রুবি আপনাকে হ্যান্ডলার রেজিস্টার করতে দেয় যা প্রোগ্রাম এক্সিট হলে কল হয়। এর একাধিক হতে পারে - সেগুলো রেজিস্টার হওয়ার বিপরীত ক্রমে কল হয়। এটা কেমন দেখায়:

at_exit do
  puts "handler 1"
end
at_exit do
  puts "handler 2"
end
# এক্সিট হলে "handler2\nhandler1" আউটপুট দেয়

এক্সিট হ্যান্ডলার এক্সিট কোড ওভাররাইড করতে পারে। আপনি হ্যান্ডলারের ভিতর থেকে exit কল করে এটি করতে পারেন। যদিও এতে মনে হয় ইনফিনিট লুপ হবে, কিন্তু হয় না। :)

at_exit do
  exit 100
end
exit 0
# এই প্রোগ্রাম 100 কোডের সাথে এক্সিট করে

যদি আপনি কোনো কলব্যাক ছাড়া এক্সিট করতে চান, তবে আপনি exit! মেথড ব্যবহার করে এটি করতে পারেন। কিন্তু মনে রাখবেন যে এটি সমস্যা সৃষ্টি করতে পারে যদি আপনার জেম বা অন্যান্য থার্ড-পার্টি কোড সেই কলব্যাকের ওপর নির্ভরশীল থাকে।

একটি রোমাঞ্চক তথ্য

প্রকাশ পেলো যে অনেক লাইব্রেরি at_exit ব্যবহার করে ক্রিয়েটিভ - এবং কিছু কেউ বলতে পারে হ্যাকি - উপায়ে। উদাহরণস্বরূপ, Sinatra একটি at_exit হুক ব্যবহার করে ওয়েব অ্যাপ বুট আপ করার জন্য। এটি নিশ্চিত করে যে সার্ভার শুরু করার আগে আপনার সকল কোড লোড হয়ে গেছে। এটা কেমন দেখায়:

module Sinatra
  class Application < Base
    ...
    at_exit { Application.run! if $!.nil? && Application.run? }
  end
end

এই সম্পর্কে Arkency ব্লগে একটি চমৎকার পোস্ট আছে: Are we abusing at_exit?

  1. রুবিতে এনভায়রনমেন্ট ভেরিয়েবল মাস্টার করুন: একটি প্র্যাকটিক্যাল গাইড

  2. রুবিতে Rake মাস্টার করুন: টাস্ক অটোমেশন-এর সম্পূর্ণ গাইড

  3. রুবি ম্যাট্রিক্স বুঝতে: ডেফিনিশন, অ্যাপ্লিকেশন এবং কীভাবে তৈরি করবেন

  4. রুবি Struct ও OpenStruct: দক্ষ ভ্যালু অবজেক্টস