কম্পিউটার

রুবিতে ব্যতিক্রম ঘটলে কীভাবে আবার চেষ্টা করবেন

সব ত্রুটি মারাত্মক নয়। কেউ কেউ ইঙ্গিত দেয় যে আপনাকে আবার চেষ্টা করতে হবে। সৌভাগ্যবশত, রুবি কয়েকটি আকর্ষণীয় প্রক্রিয়া প্রদান করে যা "আবার চেষ্টা করুন" সহজ করে তোলে - যদিও সেগুলি সবই সুস্পষ্ট বা সুপরিচিত নয়। এই পোস্টে আমরা এই মেকানিজমগুলি এবং বাস্তব জগতে কীভাবে কাজ করে তা দেখব৷

প্রবর্তন করা হচ্ছে retry

ঠিক আছে - এটি এক ধরণের সুস্পষ্ট, কিন্তু শুধুমাত্র যদি আপনি জানেন যে এটি বিদ্যমান। ব্যক্তিগতভাবে, আমি আনন্দদায়ক "পুনরায় চেষ্টা" কীওয়ার্ড সম্পর্কে জানার আগে আমার রুবি ক্যারিয়ারে ভালো ছিলাম৷

রুবির ব্যতিক্রম রেসকিউয়িং সিস্টেমে পুনরায় চেষ্টা করুন। এটা বেশ সহজ. আপনি যদি আপনার রেসকিউ ব্লকে "পুনরায় চেষ্টা করুন" ব্যবহার করেন তবে এটি কোডের বিভাগটিকে আবার চালানোর কারণ করে। আসুন একটি উদাহরণ দেখি।

begin
  retries ||= 0
  puts "try ##{ retries }"
  raise "the roof"
rescue
  retry if (retries += 1) < 3
end

# ... outputs the following:
# try #0
# try #1
# try #2

এখানে কয়েকটি বিষয় উল্লেখ্য রয়েছে:

  • যখন পুনরায় চেষ্টা করা হয়, সমস্ত শুরু এবং উদ্ধারের মধ্যে কোডটি আবার চালানো হয়। এটা অবশ্যই করবে না "যেখান থেকে ছেড়ে গেছে সেখান থেকে তুলে নিন" বা এরকম কিছু।

  • আপনি যদি পুনরায় চেষ্টা সীমিত করার জন্য কিছু ব্যবস্থা না দেন, তাহলে আপনি একটি অসীম লুপ দিয়ে শেষ হয়ে যাবেন।

  • শুরু এবং রেসকিউ ব্লক উভয়ের কোডই অভিভাবক সুযোগে একই পুনঃপ্রচার পরিবর্তনশীল অ্যাক্সেস করতে সক্ষম।

retry এর সমস্যা

পুনঃপ্রচেষ্টা দুর্দান্ত হলেও এর কিছু সীমাবদ্ধতা রয়েছে। প্রধান হল পুরো শুরু ব্লক পুনরায় চালানো হয়. কিন্তু কখনও কখনও এটি আদর্শ নয়৷

উদাহরণস্বরূপ, কল্পনা করুন যে আপনি এমন একটি রত্ন ব্যবহার করছেন যা আপনাকে একটি একক পদ্ধতি কল ব্যবহার করে Twitter, Facebook এবং অন্যান্য অনেক সাইটগুলিতে স্থিতি আপডেট পোস্ট করতে দেয়৷ এটি দেখতে এরকম কিছু হতে পারে৷

SocialMedia.post_to_all("Zomg! I just ate the biggest hamburger")

# ...posts to Twitter API
# ...posts to Facebook API
# ...etc

যদি APIগুলির একটি সাড়া দিতে ব্যর্থ হয়, তাহলে রত্নটি একটি SocialMedia::TimeoutError উত্থাপন করে এবং বাতিল করে। যদি আমরা এই ব্যতিক্রমটি ধরি এবং পুনরায় চেষ্টা করি, তাহলে আমরা সদৃশ পোস্টগুলি দিয়ে শেষ করব কারণ পুনরায় চেষ্টা শুরু থেকে শুরু হবে৷

begin
  SocialMedia.post_to_all("Zomg! I just ate the biggest hamburger")
rescue SocialMedia::TimeoutError
  retry
end

# ...posts to Twitter API
# facebook error
# ...posts to Twitter API
# facebook error
# ...posts to Twitter API
# and so on

আমরা যদি রত্নকে বলতে সক্ষম হই তাহলে কি ভালো হবে না "শুধু ফেসবুক এড়িয়ে যান, এবং পোস্ট করার জন্য API-এর তালিকার নিচে যেতে থাকুন।"

সৌভাগ্যবশত আমাদের জন্য, রুবি আমাদের ঠিক সেটাই করতে দেয়।

দ্রষ্টব্য:অবশ্যই এই সমস্যার আসল সমাধান হল সোশ্যাল মিডিয়া লাইব্রেরীকে পুনরায় স্থপতি করা। কিন্তু আমি আপনাকে যে কৌশলগুলি দেখাতে যাচ্ছি তার একমাত্র ব্যবহার-ক্ষেত্র থেকে এটি অনেক দূরে।

উদ্ধার ধারাবাহিকতা

ধারাবাহিকতা মানুষকে ভয় দেখায়। কিন্তু এটি শুধুমাত্র কারণ তারা খুব ঘন ঘন ব্যবহার করা হয় না এবং তারা একটু অদ্ভুত দেখায়। কিন্তু একবার আপনি বুঝবেন সেগুলি সত্যিই বেশ সহজ৷

একটি ধারাবাহিকতা আপনার কোডের একটি "সেভ পয়েন্ট" এর মতো, ঠিক একটি ভিডিও গেমের মতো৷ আপনি চলে যেতে পারেন এবং অন্যান্য কাজ করতে পারেন, তারপরে সেভ পয়েন্টে ফিরে যান এবং সবকিছু আপনি যেমন রেখেছিলেন তেমনই হবে।

...ঠিক আছে, তাই এটি একটি নিখুঁত উপমা নয়, তবে এটি এক ধরনের কাজ করে। আসুন কিছু কোড দেখি:

require "continuation"
counter = 0
continuation = callcc { |c| c } # define our savepoint
puts(counter += 1)
continuation.call(continuation) if counter < 5 # jump back to our savepoint

আপনি হয়ত কিছু অদ্ভুত জিনিস লক্ষ্য করেছেন। আসুন সেগুলি দিয়ে যাই:

  • আমরা একটি Continuation অবজেক্ট তৈরি করতে callcc পদ্ধতি ব্যবহার করি। এর জন্য কোন পরিষ্কার OO সিনট্যাক্স নেই।

  • প্রথমবার continuation ভেরিয়েবল বরাদ্দ করা হয়, এটি callcc এর রিটার্ন মান সেট করা হয় এর ব্লক। সেজন্য ব্লকটি সেখানে থাকতে হবে।

  • প্রতিবার আমরা যখনই সেভপয়েন্টে ফিরে যাই, তখন continuation আমরা call পাস করি না কেন, ভেরিয়েবলকে বরাদ্দ করা হয় পদ্ধতি তাই আমরা অদ্ভুত চেহারা continuation.call(continuation) ব্যবহার করি সিনট্যাক্স।

ব্যতিক্রমগুলিতে ধারাবাহিকতা যোগ করা

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

begin
  raise "the roof"
  puts "The exception was ignored"
rescue => e
  e.skip
end

# ...outputs "The exception was ignored"

এটি করার জন্য আমাকে কয়েকটি পাপ করতে হবে। Exception শুধু একটি ক্লাস। তার মানে আমি একটি skip যোগ করতে এটিকে monekypatch করতে পারি পদ্ধতি।

class Exception
  attr_accessor :continuation
  def skip
    continuation.call
  end
end

এখন আমাদের continuation সেট করতে হবে প্রতিটি ব্যতিক্রমের জন্য বৈশিষ্ট্য। দেখা যাচ্ছে যে raise শুধুমাত্র একটি পদ্ধতি, যা আমরা ওভাররাইড করতে পারি।

বিটিডব্লিউ, নিচের কোডটি প্রায় মৌখিকভাবে নেওয়া হয়েছে অ্যাডভির চমৎকার স্লাইড ডেক থিংস থেকে যা আপনি ব্যতিক্রম সম্পর্কে জানেন না। আমি এটির চেয়ে এটি বাস্তবায়নের একটি ভাল উপায় ভাবতে পারিনি:

require 'continuation'
module StoreContinuationOnRaise
  def raise(*args)
    callcc do |continuation|
      begin
        super
      rescue Exception => e
        e.continuation = continuation
        super(e)
      end
    end
  end
end

class Object
  include StoreContinuationOnRaise
end

এখন আমি skip কল করতে পারি কোনো ব্যতিক্রমের জন্য পদ্ধতি এবং এটি এমন হবে যে ব্যতিক্রম কখনো ঘটেনি।


  1. রুবিতে ব্যতিক্রম ঘটলে স্থানীয় এবং ইনস্ট্যান্স ভেরিয়েবল লগ করা

  2. রুবিতে পরিবেশের ভেরিয়েবলগুলি কীভাবে ব্যবহার করবেন

  3. একটি ম্যাট্রিক্স কি এবং রুবিতে এটি কীভাবে ব্যবহার করবেন?

  4. রুবিতে স্ট্রাকট এবং ওপেনস্ট্রাক্ট কীভাবে ব্যবহার করবেন