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