ক্যাচ ব্লকে ব্যতিক্রম এবং ব্যর্থতার মধ্যে পার্থক্য করুন [রাকু]


9

আমরা জানি যে একটি ব্যর্থতা একটি ক্যাচ ব্লক দ্বারা পরিচালনা করা যায়।

নিম্নলিখিত উদাহরণে আমরা একটি 'অ্যাডহক' ব্যর্থতা তৈরি করি (অন্য সাব-তে) এবং আমরা ব্যতিক্রমটিকে একটি ক্যাচ ব্লকে (আমার-সাব) হ্যান্ডেল করি

sub my-sub {
    try {
        CATCH {
            when X::AdHoc { say 'AdHoc Exception handled here'; .resume }
            default {say 'Other Exception'; .resume}
        }

        my $b = other-sub();

        $b.so ?? $b.say !! 'This was a Failure'.say;
    }
}

sub other-sub { fail 'Failure_X' }

my-sub();

আউটপুট নিম্নলিখিত:

AdHoc Exception handled here
This was a Failure

যদিও আমার প্রশ্নটি হল: দুটি ক্ষেত্রে পার্থক্য করার জন্য আমরা কীভাবে ক্যাচ ব্লকে ব্যর্থতা এবং একটি "সাধারণ" ব্যতিক্রমের মধ্যে পার্থক্য করতে পারি?

উত্তর:


12

Failureএবং এর মধ্যে সম্পর্কটি Exceptionহ'ল একটিতে একটি Failureরয়েছে Exception- এটি বলতে গেলে এটি তার রাজ্যের অংশ হিসাবে ব্যতিক্রমী বিষয়টিকে ধারণ করে। এটার মতো কিছু:

class Failure {
    has Exception $.exception;
    # ...
}

যখন একটি Failure"বিস্ফোরিত হয়", তখন এটি এর Exceptionভিতরে থাকাটি ফেলে দিয়ে তা করে। সুতরাং, CATCHব্লকে যা পৌঁছায় তা হ'ল Exceptionঅবজেক্ট, এবং ঘেরের সাথে কোনও লিঙ্ক নেই Failure। (আসলে, একটি প্রদত্ত Exceptionবস্তু নীতিগতভাবে অনেকগুলি দ্বারা ধারণ করতে পারে Failure))

অতএব, এটি সনাক্ত করার সরাসরি কোনও উপায় নেই। ডিজাইনের দৃষ্টিকোণ থেকে আপনার সম্ভবত হওয়া উচিত নয় এবং আপনার সমস্যা সমাধানের জন্য আলাদা উপায় খুঁজে পাওয়া উচিত। একজন Failureএক ব্যতিক্রমের নিক্ষেপ এবং অনুমোদন করার জন্য এটি একটি মান হিসাবে চিকিত্সা করা মুলতবি মাত্র একটি উপায়; অন্তর্নিহিত সমস্যার প্রকৃতি পরিবর্তিত হয় না কারণ এটি নিয়ন্ত্রণ প্রবাহের তাত্ক্ষণিক স্থানান্তর হিসাবে মান হিসাবে প্রকাশিত হয় intended দুর্ভাগ্যক্রমে, প্রশ্নটিতে মূল লক্ষ্যটি বর্ণিত হয়নি; নিয়ন্ত্রণ ব্যতিক্রমগুলি দেখতে আপনার পক্ষে এটি দরকারী মনে হতে পারে তবে অন্যথায় সম্ভবত আপনি সমাধান করার চেষ্টা করছেন এমন অন্তর্নিহিত সমস্যা সম্পর্কে অন্য একটি প্রশ্ন পোস্ট করুন। সম্ভবত আরও ভাল উপায় আছে।

সম্পূর্ণতার জন্য, আমি নোট করব যে অপ্রত্যক্ষ উপায় আছে যেগুলি সনাক্ত করতে পারে যে এটি Exceptionএকটি দ্বারা নিক্ষিপ্ত হয়েছিল Failure। উদাহরণস্বরূপ, আপনি যদি .backtraceব্যতিক্রমী অবজেক্টটি সন্ধান করেন এবং শীর্ষ ফ্রেমের প্যাকেজটি দেখুন তবে এটি নির্ধারণ করা সম্ভব যে এটি থেকে এসেছে Failure:

sub foo() { fail X::AdHoc.new(message => "foo") }
try {
    foo();
    CATCH {
        note do { no fatal; .backtrace[0].code.package ~~ Failure };
        .resume
    }
}

তবে এটি বাস্তবায়নের বিবরণগুলির উপর খুব বেশি নির্ভর করে যা সহজেই পরিবর্তিত হতে পারে, সুতরাং আমি এটির উপর নির্ভর করি না।


কেবল বিষয়গুলি স্পষ্ট করার জন্য, আমার নিবিড়তাটি কেবল ব্যাতিক্রমের জন্য হ্যান্ডেল করা (ক্যাচ ব্লকে)। কোনও ব্যর্থতার ক্ষেত্রে আমি আবার শুরু করতে চাই যেন কিছুই ঘটে না এবং বাকী কোডটি (ক্যাচের বাইরে) ব্যর্থতা পরিচালনা করতে দেয়। আমার উদাহরণে আমি প্রত্যাশা করি না যে ফিরে আসা ব্যর্থতা এতে থাকা ব্যতিক্রমটিকে ট্রিগার করবে! আমি যা করেছি তা হ'ল ফলাফলটি $ b এ পেয়ে এটি একটি বুল হিসাবে পরীক্ষা করা। এটি, আমার দৃষ্টিতে, ব্যর্থতার "ব্যবহার" গঠন করে না এবং তাই ক্যাচ ব্লকটি ট্রিগার করে! এর পরিবর্তে মনে হচ্ছে ক্যাচটি সর্বদা ব্যর্থতার মধ্যে থাকা ব্যতিক্রমটি পরিচালনা করছে !!
জাকার

আপনার উদাহরণে আরও একটি ব্যর্থতা সনাক্ত করার অপ্রত্যক্ষ উপায় সম্পর্কে, প্রত্যাবর্তিত বুল (ব্যর্থতার ধরণের স্মার্ট পরীক্ষা করে) এর মূল্য "মিথ্যা" of তবে আমি এটি "সত্য" বলে প্রত্যাশা করেছি! আমি কি কিছু রেখে গেলাম???
জাকার

1
@ জাকার এ tryব্লকটি প্রগমা বোঝায় use fatal, যার অর্থ ব্লকের যে কোনও Failureকল থেকে যে কোনও ফিরে পাওয়া তাৎক্ষণিকভাবে একটি ব্যতিক্রমে রূপান্তরিত হয়। শুধু ব্যবহার করবেন না try; একটি CATCHরাকুতে যে কোনও ব্লকে যেতে পারে (সুতরাং এটি কেবল মাত্রার স্তরে থাকুন sub)। বিকল্পভাবে, no fatalআপনার tryব্লকের শীর্ষে লিখুন ।
জোনাথন ওয়ারিংটন

এবং আমার দ্বিতীয় মন্তব্য সম্পর্কে কি?
জাকার

1
Trueস্থানীয়ভাবে রাকুডো সংস্করণে আমি প্রিন্ট দিয়েছি উদাহরণটি চালাচ্ছি। যদি এটি আপনার উপর না আসে, এটি কেবল এটি করার ভঙ্গুরতা সম্পর্কে বিন্দুটি প্রমাণ করে।
জোনাথন ওয়ারিংটন

6

কেবল tryমোড়ক মুছে ফেলুন :

sub my-sub {

#    try {              <--- remove this line...

        CATCH {
            when X::AdHoc { say 'AdHoc Exception handled here'; .resume }
            default {say 'Other Exception'; .resume}
        }

        my $b = other-sub();

        $b.so ?? $b.say !! 'This was a Failure'.say;

#    }                  <--- ...and this one

}

sub other-sub { fail 'Failure_X' }

my-sub();

আপনাকে ব্যবহৃত try। এ tryকয়েকটি জিনিস করে, তবে এখানে প্রাসঙ্গিক বিষয়টি এটি রাকুকে অবিলম্বে Failureতার সুযোগে যে কোনও একটিকে ব্যাতিক্রম করতে প্রচার করতে বলে - যা আপনি চান যা আপনি চান না । সুতরাং সহজ সমাধানটি কেবল এটি করা বন্ধ করা।


এই উত্তরটি কেবলমাত্র মৌখিকভাবে জান্টনের ব্যাখ্যাটির অংশ পুনরাবৃত্তি করেছে (তিনি তার উত্তরের নীচে লিখেছেন এমন বিশেষ মন্তব্যে দেখুন) তবে আমি নিশ্চিত ছিলাম না যে সমস্ত পাঠকই এই দিকটি স্পষ্ট / বুঝতে পারবেন, এবং ভাবেনি যে জেন্টহানের উত্তর সম্পর্কে একটি মন্তব্য বা দু'এর পক্ষে সহায়ক হবে, সুতরাং এই উত্তরটি।

আমি কোনও সম্প্রদায় থেকে উপকৃত হব না তা নিশ্চিত করার জন্য আমি এটি একটি সম্প্রদায়ের উত্তর হিসাবে লিখেছি কারণ এটি স্পষ্টতই এর নিশ্চয়তা দেয় না। এটি পর্যাপ্ত ডাউনভোটস পেলে আমরা কেবল এটি মুছে ফেলব।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.