এরর হতেই পারে। Elixir-এ অনেকে প্রায়ই বলে থাকেন "ক্র্যাশ করতে দিন", তবে কখনও কখনও সফটওয়্যার কন্ট্রাক্ট রক্ষা করতে ফাংশন কলটি রেসকিউ করে একটি পরিচিত ও নির্ভরযোগ্য অবস্থায় ফিরিয়ে আনতে হয়। কিছু ভাষায় এররকে কন্ট্রোল ফ্লোর একটি পদ্ধতি হিসেবে ব্যবহার করা হয়, কিন্তু Elixir-এ এই প্যাটার্নটি নিরুৎসাহিত করা হয়। নাম দেখেই আমরা প্রায়ই চিনতে পারি কোন ফাংশনগুলো এরর রেইজ করতে পারে: যে ফাংশনগুলো এরর রেইজ করে, তাদের নামের শেষে ! থাকে। এটি এমন ফাংশনের তুলনায়, যারা {:ok, value} বা :error রিটার্ন করে। লাইব্রেরির এই উদাহরণগুলো দেখুন:
Map.fetch(%{a: 1}, :b)
# => :error
Map.fetch!(%{a: 1}, :b)
# => raises KeyError
Elixir-এ try .. rescue ব্যবহার করে এরর থেকে রেসকিউ করার জন্য একটি কনস্ট্রাক্ট রয়েছে।
try do
raise RuntimeError, "error"
rescue
e in RuntimeError -> :error
end
চলুন এই কনস্ট্রাক্টটি খুঁটিয়ে দেখি:
try দিয়ে ডিক্লেয়ার করা হয়।raise/2 কল করছি।rescue অংশে আমরা রেইজ হওয়া এররটির Module নামের উপর প্যাটার্ন ম্যাচ করি
->-এর বাম দিকে:
e-কে এরর স্ট্রাক্টের সাথে ম্যাচ করা হয়।in একটি কিওয়ার্ড।RuntimeError হলো সেই এরর, যা আমরা রেসকিউ করতে চাই।
_ ব্যবহার করতে পারতাম, অথবা in কিওয়ার্ডটি পুরোপুরি বাদ দিতে পারতাম।এইভাবে রেসকিউ করা এররগুলো (কখনও কখনও এদের এক্সেপশনও বলা হয়) হলো স্ট্রাক্ট। Elixir-এ এরর রেসকিউ করা হয় খুব কম। সাধারণত রেসকিউ করা এররটি লগ করা হয় বা বাইরের কোনো মনিটরিং সার্ভিসে পাঠানো হয়, তারপর আবার রেইজ করা হয়। এর মানে হলো, নির্দিষ্ট এরর স্ট্রাক্টটির ভেতরের গঠন নিয়ে আমাদের সাধারণত ভাবতে হয় না।
এক্সেপশন কনসেপ্ট থেকে আপনি এরর স্ট্রাক্ট সম্পর্কে আরও জানতে পারবেন, যার মধ্যে নিজের কাস্টম এরর ডিফাইন করার বিষয়টাও থাকবে।
Instruments of Texas-এ কাজ করার সময়, আপনাকে Elixir-এ লেখা একটি পরীক্ষামূলক Reverse Polish Notation [RPN] ক্যালকুলেটর নিয়ে কাজ করার দায়িত্ব দেওয়া হয়েছে। আপনার দল কিছু অপারেশনে এরর ওঠা এবং প্রসেস ক্র্যাশ হওয়ার সমস্যায় পড়েছে। আপনাকে এমন একটি ফাংশন লেখার দায়িত্ব দেওয়া হয়েছে, যা অপারেশন ফাংশনটিকে র্যাপ করে, যাতে idiomatic Elixir কোড দিয়ে এররগুলো আরও সুন্দরভাবে হ্যান্ডেল করা যায়।
calculate!/2 ফাংশনটি ইমপ্লিমেন্ট করুন, যাতে অপারেশন ফাংশনটিকে একমাত্র আর্গুমেন্ট হিসেবে স্ট্যাক দিয়ে কল করা যায়। অপারেশন ফাংশনটি অন্য কোথাও ডিফাইন করা আছে, তবে আপনি জানেন যে এটি হয় সফলভাবে সম্পন্ন হতে পারে, নয়তো একটি এরর রেইজ করতে পারে।
stack = []
operation = fn _ -> :ok end
RPNCalculator.calculate!(stack, operation)
# => :ok
stack = []
operation = fn _ -> raise ArgumentError, "An error occurred" end
RPNCalculator.calculate!(stack, operation)
# => ** (ArgumentError) An error occurred
!দিয়ে শেষ হওয়া ফাংশনের নাম প্রোগ্রামারদের জন্য একটি সতর্কবার্তা, যে এই ফাংশনটি একটি এরর রেইজ করতে পারে।
আরও গবেষণা করতে গিয়ে আপনি লক্ষ্য করেন যে অনেক ফাংশন তাদের সফলতা বা ব্যর্থতা বোঝাতে অ্যাটম ও টাপল ব্যবহার করে। এই কৌশল ব্যবহার করে calculate/2 ইমপ্লিমেন্ট করুন।
stack = []
operation = fn _ -> "operation completed" end
RPNCalculator.calculate(stack, operation)
# => {:ok, "operation completed"}
stack = []
operation = fn _ -> raise ArgumentError, "An error occurred" end
RPNCalculator.calculate(stack, operation)
# => :error
কিছু এররে এমন গুরুত্বপূর্ণ তথ্য থাকে, যা সিস্টেমের সঠিকভাবে চলা নিশ্চিত করতে আপনার সহকর্মীদের জানা দরকার। এরর মেসেজটি পৌঁছে দিতে calculate_verbose/2 ইমপ্লিমেন্ট করুন। এররটি একটি স্ট্রাক্ট, যার একটি :message ফিল্ড থাকে।
stack = []
operation = fn _ -> "operation completed" end
RPNCalculator.calculate_verbose(stack, operation)
# => {:ok, "operation completed"}
stack = []
operation = fn _ -> raise ArgumentError, "An error occurred" end
RPNCalculator.calculate_verbose(stack, operation)
# => {:error, "An error occurred"}
Exercism-এ সাইন আপ করুন, Elixir ট্র্যাকের 58টি কনসেপ্ট168টি অনুশীলনী আর সত্যিকারের মানুষের মেন্টরিং দিয়ে শিখুন ও দক্ষ হয়ে উঠুন, সম্পূর্ণ বিনামূল্যে।