এটি রুবিতে একটি সাধারণ প্যাটার্ন যা উদ্ধার এবং ব্যতিক্রম এবং অন্য ধরণের ব্যতিক্রম পুনরায় উত্থাপন করা। অ্যাকশনভিউ এর একটি সত্যই সুস্পষ্ট উদাহরণ। যেমনটি আমি ট্রেসপয়েন্ট সম্পর্কে একটি আগের ব্লগ পোস্টে উল্লেখ করেছি, অ্যাকশনভিউ আপনার টেমপ্লেটগুলিতে যা কিছু ব্যতিক্রম ঘটবে তা গ্রাস করে এবং সেগুলিকে একটি ActionView::TemplateError
হিসাবে পুনরায় উত্থাপন করে। .
কখনও কখনও এই যথেষ্ট ভাল না. আপনার সত্যিই সেই আসল ব্যতিক্রমটি প্রয়োজন কারণ এতে কিছু ডেটা রয়েছে যা আপনাকে একটি সমস্যা সমাধান করতে সহায়তা করবে। সৌভাগ্যবশত, রুবি 2.1 অনুযায়ী, আপনি এটি করতে ব্যতিক্রম# কারণ পদ্ধতি ব্যবহার করতে পারেন।
চলুন দেখি কিভাবে এটি অনুশীলনে কাজ করে। এখানে, আমরা একটি NoMethodError
উত্থাপন করি , তারপর অবিলম্বে এটি গিলে ফেলুন এবং একটি RuntimeError
উত্থাপন করুন . তারপর আমরা RuntimeError
ধরি এবং আসল NoMethodError
পেতে #cause ব্যবহার করুন .
def fail_and_reraise
raise NoMethodError
rescue
raise RuntimeError
end
begin
fail_and_reraise
rescue => e
puts "#{ e } caused by #{ e.cause }"
end
নেস্টেড ব্যাকট্রেস এবং কাস্টম বৈশিষ্ট্য
#cause পদ্ধতি আসলে আসল ব্যতিক্রম বস্তু ফেরত দেয়। এর মানে হল যে আপনি যে কোনও মেটাডেটা অ্যাক্সেস করতে পারেন যা মূল ব্যতিক্রমের অংশ ছিল। আপনি আসল ব্যাকট্রেসও পেতে পারেন।
class EatingError < StandardError
attr_reader :food
def initialize(food)
@food = food
end
end
def fail_and_reraise
raise EatingError.new("soup")
rescue
raise RuntimeError
end
begin
fail_and_reraise
rescue => e
puts "#{ e } caused by #{ e.cause } while eating #{ e.cause.food }"
puts e.cause.backtrace.first
end
অনন্তে এবং তার বাইরে!
যদিও উপরের উদাহরণগুলি শুধুমাত্র এক স্তরের গভীর, রুবিতে নেস্টেড ব্যতিক্রমগুলির যে কোনও সংখ্যক স্তর থাকতে পারে। আমি আশ্চর্য হব যদি আপনাকে কখনও চারটি স্তরের মধ্যে তিনটির বেশি গভীরে যেতে হয়৷
...কিন্তু শুধুমাত্র মজার জন্য আমি ভেবেছিলাম আমি একটি 100-স্তরের গভীর নেস্টেড ব্যতিক্রম তৈরি করার চেষ্টা করব। এটি কোডের একটি মূর্খ ছোট টুকরা, এবং আমি আশা করি আপনি এটি উৎপাদনে এর মতো দেখতে পাবেন না৷
def recursively_raise(c=0)
raise "Level #{ c }"
rescue => e
if c < 100
recursively_raise(c + 1)
else
recursively_print(e)
end
end
def recursively_print(e)
if e
puts e
recursively_print(e.cause)
end
end
recursively_raise()
# ... Prints the following:
# Level 100
# Level 99
# Level 98
# etc.