কম্পিউটার

গতিশীল ব্যতিক্রম ম্যাচার সহ লেভেল আপ `রেসকিউ`

আপনি যখন রুবিতে একটি রেসকিউ ক্লজ ব্যবহার করেন, তখন আপনি কী ধরনের ব্যতিক্রম উদ্ধার করতে চান তা নির্দিষ্ট করতে পারেন। আপনাকে যা করতে হবে তা হল এর মত ব্যতিক্রম ক্লাসের একটি তালিকা প্রদান করুন:

begin
  raise RuntimeError
rescue RuntimeError, NoMethodError
  puts "rescued!"
end

কিন্তু আপনি যদি কোডটি লেখার সময় ব্যতিক্রম ক্লাসটি কী হবে তা যদি আপনি না জানেন? সবচেয়ে সুস্পষ্ট উত্তর হল সমস্ত ব্যতিক্রম উদ্ধার করা, কিছু ধরণের পরীক্ষা করা এবং তারপরে পাস না হওয়া ব্যতিক্রমগুলিকে পুনরায় উত্থাপন করা। এরকম কিছু:

begin
  raise "FUBAR! The ship's going down!"
rescue => e
  raise unless e.message =~ /^FUBAR/
  ... do something ...
end

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

কিভাবে রেসকিউ ব্যতিক্রমের সাথে মেলে

রেসকিউ ব্লকের ভিতরে একটি ব্যতিক্রম ঘটলে, রুবি ইন্টারপ্রেটার আপনার দেওয়া ব্যতিক্রম ক্লাসের তালিকার বিপরীতে ব্যতিক্রমের ক্লাস পরীক্ষা করে। যদি একটি মিল থাকে, তবে ব্যতিক্রমটি উদ্ধার করা হয়।

মিলটি এইরকম কিছু দেখায়:

exception_classes_to_rescue.any? do |c|
  c === raised_exception.class
end

রুবিতে অন্য অপারেটরের মতো, === সহজভাবে একটি পদ্ধতি। এই ক্ষেত্রে এটি c এর একটি পদ্ধতি . তাহলে আমরা কি করতে পারি যদি আমরা আমাদের নিজস্ব === সংজ্ঞায়িত করি পদ্ধতি?

নীচের উদাহরণে আমি Anything নামে একটি ক্লাস তৈরি করছি যেখানে  Anything === x x এর যেকোনো মানের জন্য সত্য ফেরত দেয়। যদি আমি এই শ্রেণীটিকে উদ্ধারের যুক্তি হিসাবে দিই, তবে এটি সমস্ত ব্যতিক্রমগুলিকে উদ্ধার করে।

class Anything
  def self.===(exception)
    true
  end
end

begin
  raise EOFError
rescue Anything
  puts "It rescues ANYTHING!"
end

যদিও সমস্ত ব্যতিক্রমগুলি উদ্ধার করার আরও ভাল উপায় রয়েছে, এই কোডটি আকর্ষণীয় কারণ এটি আমাদের দুটি জিনিস দেখায়:

  1. আপনি রেসকিউ ক্লজ ক্লাস দিতে পারেন যেগুলি Exception থেকে উত্তরাধিকারসূত্রে পাওয়া যায় না , যতক্ষণ না তারা === প্রয়োগ করে

  2. আপনি যদি === নিয়ন্ত্রণ করেন , আপনি কোন ব্যতিক্রমগুলি উদ্ধার করা হবে তা নিয়ন্ত্রণ করতে পারেন৷

বার্তার উপর ভিত্তি করে ব্যতিক্রমগুলি উদ্ধার করা

আমরা এখন যা জানি তা জেনে, কোড লেখা সহজ যা শুধুমাত্র ব্যতিক্রমগুলিকে উদ্ধার করে যদি ব্যতিক্রমের বার্তাটি একটি প্যাটার্নের সাথে মিলে যায়৷

class AllFoobarErrors
  def self.===(exception)
    # rescue all exceptions with messages starting with FOOBAR 
    exception.message =~ /^FOOBAR/
  end
end

begin
  raise EOFError, "FOOBAR: there was an eof!"
rescue AllFoobarErrors
  puts "rescued!"
end

কাস্টম বৈশিষ্ট্যের উপর ভিত্তি করে ব্যতিক্রমগুলি উদ্ধার করা

যেহেতু আপনার কাছে ব্যতিক্রম বস্তুর অ্যাক্সেস আছে, আপনার ম্যাচার সেই বস্তুর ভিতরে থাকা যেকোনো ডেটা ব্যবহার করতে পারে।

এক মুহুর্তের জন্য কল্পনা করুন যে আপনার কাছে একটি ব্যতিক্রম আছে যার একটি কাস্টম বৈশিষ্ট্য রয়েছে যার নাম "তীব্রতা"। আপনি ব্যতিক্রমের সমস্ত "নিম্ন তীব্রতা" ঘটনাগুলিকে গ্রাস করতে চান, তবে যেকোনো "উচ্চ তীব্রতা" ঘটনাগুলিকে পাস করতে দিন৷ আপনি এটিকে এভাবে বাস্তবায়ন করতে পারেন:

class Infraction < StandardError
  attr_reader :severity
  def initialize(severity)
    @severity = severity
  end
end

class LowSeverityInfractions
  def self.===(exception)
    exception.is_a?(Infraction) && exception.severity == :low
  end
end

begin
  raise Infraction.new(:low)
rescue LowSeverityInfractions
  puts "rescued!"
end

এটিকে গতিশীল করা

এই সবই বেশ চমৎকার, কিন্তু এতে প্রচুর বয়লারপ্লেট কোড জড়িত। প্রতিটি ম্যাচারের জন্য ম্যানুয়ালি আলাদা ক্লাস সংজ্ঞায়িত করা অত্যধিক বলে মনে হচ্ছে। সৌভাগ্যবশত আমরা একটু মেটাপ্রোগ্রামিং ব্যবহার করে এটিকে কিছুটা শুকিয়ে নিতে পারি।

নীচের উদাহরণে, আমরা একটি পদ্ধতি সংজ্ঞায়িত করছি যা আমাদের জন্য ম্যাচার ক্লাস তৈরি করে। আপনি একটি ব্লকের মাধ্যমে ম্যাচিং লজিক প্রদান করেন এবং ম্যাচিং জেনারেটর একটি নতুন ক্লাস তৈরি করে যা তার === এর ভিতরে ব্লক ব্যবহার করে পদ্ধতি।

def exceptions_matching(&block)
  Class.new do
    def self.===(other)
      @block.call(other)
    end
  end.tap do |c|
    c.instance_variable_set(:@block, block)
  end
end

begin
  raise "FOOBAR: We're all doomed!"
rescue exceptions_matching { |e| e.message =~ /^FOOBAR/ }
  puts "rescued!"
end

লবণের একটি দানা

রুবির অনেক দুর্দান্ত কৌশলের মতো, আমি ঠিক করতে পারি না যে এই সবগুলি পাগলামি নাকি একটি দুর্দান্ত ধারণা। হয়তো এটা উভয়ের সামান্য. যদিও আমি স্পষ্টভাবে সুপারিশ করব না যে আপনি প্রথম পছন্দ হিসাবে এই কৌশলটির জন্য পৌঁছান, আমি দেখতে পাচ্ছি যে এটি উপরেরটির মতো পরিস্থিতিতে কীভাবে কার্যকর হবে যেখানে আপনি তীব্রতার উপর ভিত্তি করে ব্যতিক্রমগুলি উদ্ধার করতে চান। যাই হোক না কেন, এটি আপনার টুলবেল্টের আরেকটি টুল!


  1. কিভাবে আপনার iPhone দিয়ে উইন্ডোজ ডায়নামিক লক কনফিগার করবেন

  2. রেলের সাথে হটওয়্যার ব্যবহার করা

  3. Pry এ ব্যতিক্রমের সাথে কাজ করা

  4. ডাইনামিক লক ফিচার দিয়ে কিভাবে উইন্ডোজ 10 সুরক্ষিত করা যায়