কেন চেষ্টা করুন ... অবশেষে ক্যাচ ক্লজ ছাড়াই?


79

প্রোগ্রামে ক্লাসিকাল উপায়টি রয়েছে try ... catch। যখন এটি ব্যবহার করতে উপযুক্ত tryছাড়া catch?

পাইথনে নিম্নলিখিতটি আইনী বলে মনে হচ্ছে এবং তা বোধগম্য হতে পারে:

try:
  #do work
finally:
  #do something unconditional

তবে কোডটি catchকিছুই দেয়নি । একইভাবে কেউ জাভাতে ভাবতে পারেন এটি নীচে হবে:

try {
    //for example try to get a database connection
}
finally {
  //closeConnection(connection)
}

এটি দেখতে দুর্দান্ত লাগছে এবং হঠাৎ আমাকে ব্যতিক্রমের ধরণের ইত্যাদি নিয়ে চিন্তা করতে হবে না যদি এটি ভাল অনুশীলন হয় তবে এটি কখন ভাল অনুশীলন হয়? বিকল্পভাবে, এটি ভাল অনুশীলন না হওয়া বা আইনী না হওয়ার কারণগুলি কী কী? (আমি উত্সটি সংকলন করি নি Java আমি এটি সম্পর্কে জিজ্ঞাসা করছি কারণ এটি জাভাটির জন্য একটি সিনট্যাক্স ত্রুটি হতে পারে I আমি পরীক্ষা করেছিলাম যে পাইথন অবশ্যই সংকলন করেছে))

একটি সম্পর্কিত সমস্যা যার মধ্যে আমি চলে এসেছি তা হ'ল: আমি ফাংশন / পদ্ধতিটি লিখতে থাকি, শেষে এটি অবশ্যই কিছু ফেরত দেয়। তবে এটি এমন জায়গায় থাকতে পারে যা পৌঁছানো উচিত নয় এবং এটি অবশ্যই একটি রিটার্ন পয়েন্ট হতে হবে। সুতরাং, আমি উপরের ব্যতিক্রমগুলি পরিচালনা করি তা সত্ত্বেও, আমি এখনও ফিরে আসছি NULLবা কোডের কোনও পর্যায়ে একটি ফাঁকা স্ট্রিং যা পৌঁছানো উচিত নয়, প্রায়শই পদ্ধতি / ফাংশনের শেষ। আমি সর্বদা কোডটি পুনর্গঠন করতে সক্ষম হয়েছি যাতে এটির প্রয়োজন না হয় return NULL, যেহেতু এটি পুরোপুরি ভাল অনুশীলনের চেয়ে কম দেখায়।


4
জাভাতে, রিটার্নের স্টেটমেন্টটি চেষ্টা ব্লকের শেষে রাখবেন না কেন?
কেভিন ক্লায়ান

2
আমি দু: খিত যে চেষ্টা করুন..ফিনালি এবং চেষ্টা করুন। সিলেক্ট উভয়ই চেষ্টা কীওয়ার্ডটি ব্যবহার করুন, উভয়ই চেষ্টা করে শুরু না করে তারা 2 সম্পূর্ণ ভিন্ন নির্মাণ।
পিটার বি

3
try/catch"প্রোগ্রাম করার শাস্ত্রীয় উপায়" নয়। এটি ক্লাসিকাল সি ++ প্রোগ্রামের উপায়, কারণ সি ++ এর যথাযথ চেষ্টা / অবশেষে নির্মাণের অভাব রয়েছে, যার অর্থ আপনাকে আরআইআই জড়িত কুৎসিত হ্যাকগুলি ব্যবহার করে গ্যারান্টেড রিভার্সিবল স্টেট পরিবর্তনগুলি প্রয়োগ করতে হবে। তবে শালীন ওও ভাষাগুলিতে সেই সমস্যা নেই কারণ তারা শেষ পর্যন্ত চেষ্টা করে provide এটি চেষ্টা / ধরনের চেয়ে খুব আলাদা উদ্দেশ্যে ব্যবহার করা হয়।
ম্যাসন হুইলারের

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

4
@ ম্যাসনভিয়েল " কুশলী হ্যাকস" দয়া করে, কোনও জিনিসটির নিজস্ব ক্লিনআপ হ্যান্ডেল করা কী খারাপ তা ব্যাখ্যা করুন?
বাল্ড্রিক

উত্তর:


146

এটি নির্ভর করে যে আপনি এই সময়ে উত্থাপিত ব্যতিক্রমগুলি মোকাবেলা করতে পারবেন কিনা তার উপর depends

আপনি যদি স্থানীয়ভাবে ব্যতিক্রমগুলি পরিচালনা করতে পারেন তবে ত্রুটিটি যতটা সম্ভব উত্থাপিত হয় তার কাছাকাছি হ্যান্ডেল করা ভাল।

যদি আপনি এগুলি স্থানীয়ভাবে পরিচালনা করতে না পারেন তবে কেবল একটি try / finallyব্লক থাকা পুরোপুরি যুক্তিসঙ্গত - ধরে নেওয়া পদ্ধতিটি সফল হয়েছে কিনা তা নির্বিশেষে আপনার কিছু কোড কার্যকর করতে হবে। উদাহরণস্বরূপ ( নীলের মন্তব্য থেকে ), একটি স্ট্রিম খোলার এবং তারপরে সেই স্ট্রিমটি বোঝার জন্য কোনও অভ্যন্তরীণ পদ্ধতিতে প্রেরণ করা আপনার যখন প্রয়োজন তখন একটি দুর্দান্ত উদাহরণ এটি try { } finally { }নিশ্চিত করার জন্য শেষ ধারাটি ব্যবহার করে সাফল্য বা নির্বিশেষে স্ট্রিমটি বন্ধ হয়ে গেছে বা পড়ার ব্যর্থতা।

তবে, আপনার কোডটির কোথাও আপনার এখনও একটি ব্যতিক্রম হ্যান্ডলার প্রয়োজন হবে - আপনি না চাইলে আপনার অ্যাপ্লিকেশন অবশ্যই অবশ্যই ক্র্যাশ হয়। এটি হ্যান্ডলারটি ঠিক কোথায় আপনার অ্যাপ্লিকেশনটির আর্কিটেকচারের উপর নির্ভর করে।


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

13
@ উইল - এই কারণেই আমি "সম্ভব হিসাবে" বাক্যাংশটি ব্যবহার করেছি।
ChrisF

8
উত্তম উত্তর, তবে আমি একটি উদাহরণ যোগ করব: একটি স্ট্রিম খুলুন এবং সেই স্ট্রিমটি বোঝার জন্য কোনও অভ্যন্তরীণ পদ্ধতিতে প্রবাহ করা আপনার যখন প্রয়োজন তখন একটি দুর্দান্ত উদাহরণ try { } finally { }, শেষ অবধি ধারাটির সদ্ব্যবহার করা শেষ পর্যন্ত সাফল্য / নির্বিশেষে বন্ধ হয়ে যায় তা নিশ্চিত করার জন্য ব্যর্থতা.
নীল

কারণ কখনও কখনও শীর্ষে থাকা সমস্ত লোকের মতোই কাছাকাছি হয়
নিউটোপিয়ান

"কেবল একবার চেষ্টা / অবশেষে অবরুদ্ধ হওয়া পুরোপুরি যুক্তিসঙ্গত" এই উত্তরটির সন্ধান করছিল। তোমাকে ধন্যবাদ @ChrisF
Neal aise

36

এই finallyব্লকটি কোডের জন্য ব্যবহৃত হয় যা সর্বদা চলতে হবে, ত্রুটির শর্তটি (ব্যতিক্রম) ঘটেছে কিনা not

finallyব্লকটির কোডটি tryব্লকটি সম্পূর্ণ হওয়ার পরে এবং যদি কোনও ধরা ব্যতিক্রম ঘটে, সংশ্লিষ্ট catchব্লকটি সম্পূর্ণ হওয়ার পরে চালানো হয় । এটি সর্বদা চালিত হয়, এমনকি tryবা catchব্লকে কোনও অপ্রকাশিত ব্যতিক্রম ঘটলেও ।

finallyব্লক সাধারণত ক্লোজিং ফাইল, নেটওয়ার্ক সংযোগ, ইত্যাদি যে খোলা হয় জন্য ব্যবহার করা হয় tryব্লক। কারণটি হ'ল ফাইল বা নেটওয়ার্ক সংযোগটি অবশ্যই বন্ধ করতে হবে, সেই ফাইল বা নেটওয়ার্ক সংযোগটি ব্যবহার করে অপারেশন সফল হয়েছে বা ব্যর্থ হয়েছে কিনা।

finallyএটি নিজেই কোনও ব্যতিক্রম ছুঁড়ে না ফেলে তা নিশ্চিত করার জন্য ব্লকে যত্ন নেওয়া উচিত । উদাহরণস্বরূপ, দ্বিগুণভাবে সমস্ত ভেরিয়েবল nullইত্যাদি পরীক্ষা করার জন্য নিশ্চিত হন etc.


8
+1: এটি "অবশ্যই পরিষ্কার করতে হবে" এর জন্য মূর্তিযুক্ত। বেশিরভাগ ব্যবহার try-finallyএকটি withবিবৃতি দিয়ে প্রতিস্থাপন করা যেতে পারে ।
এস .লট

12
বিভিন্ন ভাষায় try/finallyনির্মাণের ক্ষেত্রে ভাষা-সংক্রান্ত বিশেষ উন্নতি রয়েছে । সি শার্প হয়েছে using, পাইথন হয়েছে with, ইত্যাদি
yfeldblum

5
@yfeldblum - usingএবং এর মধ্যে একটি সূক্ষ্ম পার্থক্য রয়েছে try-finally, কারণ অবজেক্টের কনস্ট্রাক্টরে কোনও ব্যতিক্রম ঘটলে Disposeপদ্ধতিটি usingব্লকটি কল করবে না IDisposabletry-finallyআপনাকে কোড কার্যকর করতে অনুমতি দেয় এমনকি যদি অবজেক্টের কনস্ট্রাক্টর একটি ব্যতিক্রম ছুঁড়ে দেয়।
স্কট হুইটলক

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

1
@DeadMG: আরও দেখুন stackoverflow.com/q/14830534/18192
ব্রায়ান

17

একটি উদাহরণ যেখানে চেষ্টা করুন ... অবশেষে ক্যাচ ক্লজ ব্যতীত জাভাতে উপযুক্ত (এবং আরও বেশি, মূর্তিমাফিক ) হ'ল সহবর্তী ইউটিলিটি লকস প্যাকেজে লক ব্যবহার ।

  • এপিআই ডকুমেন্টেশনে এটি কীভাবে ব্যাখ্যা এবং ন্যায়সঙ্গত হয় তা এখানে (উদ্ধৃতিতে বোল্ড ফন্টটি আমার):

    ... ব্লক-কাঠামোগত লকিংয়ের অনুপস্থিতি সিঙ্ক্রোনাইজড পদ্ধতি এবং বিবৃতিগুলির সাথে ঘটে এমন লকগুলির স্বয়ংক্রিয় প্রকাশকে সরিয়ে দেয়। বেশিরভাগ ক্ষেত্রে নিম্নলিখিত আইডিয়মটি ব্যবহার করা উচিত :

     Lock l = ...;
     l.lock();
     try {
         // access the resource protected by this lock
     } finally {
         l.unlock();
     }

    লকিং এবং আনলকিং যখন বিভিন্ন স্কোপে ঘটে, তখন অবশ্যই লকটি রাখা অবস্থায় কার্যকর হওয়া সমস্ত কোড চেষ্টা করে শেষ পর্যন্ত বা সুরক্ষিত রয়েছে কিনা তা নিশ্চিত করার জন্য অবশ্যই প্রয়োজনীয় হওয়া আবশ্যক


আমি কি l.lock()ভিতরে চেষ্টা করতে পারি ? try{ l.lock(); }finally{l.unlock();}
RMachnik

1
প্রযুক্তিগতভাবে, আপনি পারেন। আমি এটি সেখানে রাখিনি কারণ শব্দার্থকভাবে, এটি কম বোঝায়। tryএই স্নিপেট রিসোর্স এক্সেস মোড়ানো দেয়ার উদ্দেশ্যে করা হচ্ছে, কেন যে সম্পর্কহীন কিছু সঙ্গে এটি দূষণ
মশা

4
আপনি, কিন্তু যদি পারেন l.lock()ব্যর্থ হয়, finallyব্লক এখনও চালানো হবে যদি l.lock()ভিতরে tryব্লক। আপনি যদি জনাট পরামর্শ মতো করে থাকেন তবে finallyব্লকটি কেবল তখনই চলবে যখন আমরা জানি যে লকটি অর্জিত হয়েছিল।
Wtrmute

12

একটি বেসিক স্তরে catchএবং finallyদুটি সম্পর্কিত তবে ভিন্ন সমস্যার সমাধান করুন:

  • catch আপনার কল করা কোড দ্বারা প্রতিবেদন করা একটি সমস্যা পরিচালনা করতে ব্যবহৃত হয়
  • finally বর্তমান কোডটি তৈরি / সংশোধিত তথ্য / সংস্থানগুলি পরিষ্কার করতে ব্যবহৃত হয়, সমস্যা দেখা দিয়েছে বা না আসুক তা নয়

সুতরাং উভয়ই কোনওভাবে সমস্যা (ব্যতিক্রম) এর সাথে সম্পর্কিত, তবে এগুলি তাদের মধ্যে প্রচলিত রয়েছে।

একটি গুরুত্বপূর্ণ পার্থক্য হ'ল finallyব্লকটি অবশ্যই সেই একই পদ্ধতিতে থাকতে হবে যেখানে সংস্থানগুলি তৈরি হয়েছিল (উত্স ফাঁস এড়াতে) এবং কল স্ট্যাকের কোনও আলাদা স্তরে রাখা যায় না।

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


2
নিতপিক: "... অবশেষে ব্লকটি একই পদ্ধতিতে হওয়া উচিত যেখানে সংস্থানগুলি তৈরি হয়েছিল ..." । সেভাবে এটি করা অবশ্যই একটি ভাল ধারণা , কারণ কোনও উত্স ফাঁস নেই তা দেখা সহজ see তবে এটি প্রয়োজনীয় পূর্বশর্ত নয়; অর্থাত আপনি না আছে এটা যে পথ না। আপনি সংস্থানটি ব্যবহারের finally(স্ট্যাটিকালি বা ডাইনামিকালি) চেষ্টা স্টেটমেন্টের রিসোর্সটি প্রকাশ করতে পারেন ... এবং এখনও 100% লিক-প্রুফ হতে পারেন।
স্টিফেন সি

6

@yfeldblum এর সঠিক উত্তর রয়েছে: অবশেষে একটি ক্যাচ স্টেটমেন্ট না দিয়ে চেষ্টা করুন সাধারণত একটি উপযুক্ত ভাষা নির্মাণের সাথে প্রতিস্থাপন করা উচিত।

সি ++ তে এটি আরএআইআই এবং কনস্ট্রাক্টর / ডেস্ট্রাক্টর ব্যবহার করছে; পাইথনে এটি একটি withবিবৃতি; এবং সি # এ এটি একটি usingবিবৃতি।

এগুলি প্রায় সবসময়ই মার্জিত হয় কারণ সূচনা এবং চূড়ান্তকরণ কোড দুটি জায়গায় না হয়ে এক জায়গায় (বিমূর্ত বস্তু)।



2
ধরুন আপনার কাছে খুব খারাপভাবে ডিজাইন করা অবজেক্ট রয়েছে (উদাহরণস্বরূপ, একটি যা সি # তে আইডিসপোজেবল যথাযথভাবে প্রয়োগ করে না) যা সর্বদা কার্যকর বিকল্প নয়।
mootinator

1
@ মুটিনেটর: আপনি কি খারাপভাবে ডিজাইন করা অবজেক্টের উত্তরাধিকারী হয়ে এটি ঠিক করতে পারবেন না?
নিল জি

2
নাকি এনক্যাপসুলেশন? বাঃ। আমি অবশ্যই হ্যাঁ, অবশ্যই
মটিনেটর

4

finallyরিটার্ন স্টেটমেন্টের পরে অনেক ভাষায় একটি স্টেটমেন্টও চলে runs এর অর্থ আপনি এর মতো কিছু করতে পারেন:

try {
  // Do processing
  return result;
} finally {
  // Release resources
}

কোনও ব্যতিক্রম বা নিয়মিত রিটার্ন বিবৃতি দিয়ে পদ্ধতিটি কীভাবে শেষ হয়েছিল তা বিবেচনা না করে যা সংস্থানগুলি প্রকাশ করে।

এটি ভাল বা খারাপ তা বিতর্কের পক্ষে রয়েছে তবে try {} finally {}সর্বদা ব্যতিক্রম হ্যান্ডলিংয়ের মধ্যেই সীমাবদ্ধ থাকে না।


0

আমি পাইথোনিস্টাসের ক্রোধকে ডাকতে পারি (আমি পাইথনটি বেশি ব্যবহার করি না বলে জানি না) বা অন্যান্য ভাষাগুলির প্রোগ্রামাররা এই উত্তরটি সহ উত্তর দিতে পারেন তবে আমার মতে বেশিরভাগ ফাংশনগুলিতে আদর্শভাবে বলতে গেলে কোনও ব্লক থাকা উচিত নয়catch । কেন তা দেখানোর জন্য, আমাকে এটি 80 এর দশকের শেষের দিকে এবং 90 এর দশকের গোড়ার দিকে টার্বো সি এর সাথে কাজ করার সময় ম্যানুয়াল ত্রুটি কোড প্রচারের সাথে আমার বিপরীতে তুলনা করুন।

সুতরাং আসুন আমরা বলি যে কোনও ব্যবহারকারী লোড করার জন্য একটি চিত্র ফাইল নির্বাচন করার প্রতিক্রিয়ায় একটি চিত্র বা এর মতো কিছু লোড করার জন্য আমাদের একটি ফাংশন রয়েছে এবং এটি সি এবং অ্যাসেমব্লিতে লেখা আছে:

এখানে চিত্র বর্ণনা লিখুন

আমি কয়েকটি নিম্ন-স্তরের ফাংশন বাদ দিয়েছি তবে আমরা দেখতে পাচ্ছি যে আমি ত্রুটি-পরিচালনা সংক্রান্ত তাদের যে কী দায়িত্ব রয়েছে তার উপর ভিত্তি করে রঙের কোডেড বিভিন্ন বিভাগের ফাংশনগুলি চিহ্নিত করেছি।

ব্যর্থতা এবং পুনরুদ্ধারের পয়েন্ট

এখন ফাংশনগুলির বিভাগগুলি লিখতে কখনই কঠিন ছিল না আমি "ব্যর্থতার সম্ভাব্য বিন্দু" (যেগুলি throw, অর্থাৎ) এবং "ত্রুটি পুনরুদ্ধার এবং প্রতিবেদন" ফাংশনগুলি (এটি catch, যা ) বলি ।

ঐ ফাংশন সবসময় লিখতে সঠিকভাবে সামনে ব্যতিক্রম হ্যান্ডলিং উপলব্ধ ছিল একটি ফাংশন যে মেমরি বরাদ্দ করতে ব্যর্থ মত একটি বহিস্থিত ব্যর্থতা মধ্যে চালাতে পারেন,, শুধু একটি আসতে পারেন যেহেতু তুচ্ছ ছিল NULLবা 0বা -1বা একটি বিশ্বব্যাপী ত্রুটি কোড বা এই প্রভাব কিছু সেট। এবং ত্রুটি পুনরুদ্ধার / রিপোর্টিং সর্বদা সহজ ছিল যেহেতু একবার আপনি কল স্ট্যাকের পথে এমন এক পর্যায়ে কাজ করেছিলেন যেখানে ব্যর্থতাগুলি পুনরুদ্ধার করা এবং রিপোর্ট করা বুদ্ধিমান হয়ে যায়, আপনি কেবল ত্রুটি কোড এবং / অথবা বার্তাটি গ্রহণ করেন এবং এটি ব্যবহারকারীকে রিপোর্ট করেন। এবং স্বাভাবিকভাবেই এই শ্রেণিবিন্যাসের পাতায় একটি ফাংশন যা ভবিষ্যতে এটি কীভাবে পরিবর্তিত হয় তা কখনই ব্যর্থ হতে পারে না Convert Pixel) সঠিকভাবে লিখতে (কমপক্ষে ত্রুটি পরিচালনার ক্ষেত্রে সম্মতি দিয়ে) মরে যাওয়া সহজ is

ত্রুটি প্রচার

তবে, মানব ত্রুটির প্রবণ ক্লান্তিকর কাজগুলি হ'ল ত্রুটি প্রচারকারী , যেগুলি সরাসরি ব্যর্থতার মধ্যে পড়ে না তবে এমন ক্রিয়াকলাপ বলে যেগুলি শ্রেণিবদ্ধের আরও গভীরতর জায়গায় ব্যর্থ হতে পারে। এই মুহুর্তে, Allocate Scanlineহতে পারে একটি ব্যর্থতা হ্যান্ডেল করতে mallocএবং তারপরে একটি ত্রুটি নীচে ফিরে আসতে হবে Convert Scanlines, তারপরে Convert Scanlinesসেই ত্রুটিটি পরীক্ষা করে এটি Decompress Image, তারপরে Decompress Image->Parse Imageএবং Parse Image->Load Image, এবং Load Imageব্যবহারকারী-এন্ড কমান্ডের কাছে দিতে হবে যেখানে শেষ পর্যন্ত ত্রুটিটি রিপোর্ট করা হয়েছে ।

এখান থেকেই প্রচুর মানুষ ভুল করে যেহেতু ত্রুটিটি সঠিকভাবে পরিচালনা করার ক্ষেত্রে ক্রিয়াকলাপের পুরো ক্রমক্রমটি নীচে নেমে আসতে ত্রুটিটি পরীক্ষা করতে ব্যর্থ করতে কেবল একটি ত্রুটি প্রচারকারী লাগে।

তদ্ব্যতীত, যদি ত্রুটি কোডগুলি ফাংশন দ্বারা ফিরিয়ে দেওয়া হয়, তবে আমরা বলি যে আমাদের কোডবেসের 90%, সাফল্যের উপর আগ্রহের মানগুলি ফিরিয়ে দেওয়ার ক্ষমতাটি হারাতে পারায় যেহেতু অনেকগুলি ক্রিয়াকলাপে ত্রুটি কোড ফেরত দেওয়ার জন্য তাদের রিটার্ন মান সংরক্ষণ করতে হবে ব্যর্থতা

হ্রাস মানব ত্রুটি: গ্লোবাল ত্রুটি কোডগুলি

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

এমনও কিছু ঘটনা রয়েছে যেখানে কোনও ফাংশন কোনও ত্রুটির মধ্যে দিয়ে যেতে পারে তবে পূর্ববর্তী ত্রুটিটি আবিষ্কারের ফলে অকালপূর্বে ফিরে আসার আগে এটি কিছুটা বেশি সময় চালিয়ে যাওয়া অপেক্ষাকৃত নিরীহ। এটি প্রতিটি একক ক্রিয়াকলাপে 90% ফাংশন কলগুলির বিরুদ্ধে ত্রুটিগুলি পরীক্ষা না করেই এ জাতীয় কিছু ঘটতে দেয়, সুতরাং এটি এতটুকু সাবধানতা ছাড়াই সঠিক ত্রুটি পরিচালনার অনুমতি দিতে পারে।

মানব ত্রুটি হ্রাস করা: ব্যতিক্রম-পরিচালনা

তবে, ম্যানুয়াল ত্রুটি প্রচারের নিয়ন্ত্রণ প্রবাহের দিকটি মোকাবেলার জন্য উপরের সমাধানটির এখনও অনেকগুলি ফাংশন প্রয়োজন, এমনকি যদি এটি ম্যানুয়াল if error happened, return errorধরণের কোডের লাইনের সংখ্যা হ্রাস করে । এটি এটিকে পুরোপুরি সরিয়ে ফেলবে না কারণ এখনও প্রায়শই একটি ত্রুটির জন্য কমপক্ষে একটি জায়গা যাচাই করা এবং প্রায় প্রতিটি ত্রুটি প্রচারের জন্য ফিরে আসা প্রয়োজন। দিনটি বাছাই করতে ব্যতিক্রম-হ্যান্ডলিং ছবিটিতে আসে তাই এটি হয়।

তবে এখানে ব্যতিক্রম হ্যান্ডলিংয়ের মান হ'ল ম্যানুয়াল ত্রুটি প্রচারের নিয়ন্ত্রণ প্রবাহের দিকটি মোকাবেলার প্রয়োজন মুক্ত করা। এর অর্থ এর কোডটি catchআপনার কোডবেজ জুড়ে কোনও নৌকা বোঝা চাপতে এড়াতে সক্ষমতার সাথে আবদ্ধ । উপরের চিত্রটিতে, কেবলমাত্র যেখানে catchব্লক থাকা উচিত Load Image User Commandসেখানেই ত্রুটিটি প্রতিবেদন করা হয়েছে। অন্য কিছুতে আদর্শভাবে কিছু হওয়া উচিত নয় catchকারণ অন্যথায় এটি তাত্ক্ষণিক এবং ত্রুটিযুক্ত কোড হ্যান্ডলিংয়ের মতো ত্রুটি-প্রবণ হিসাবে পেতে শুরু করেছে।

সুতরাং যদি আপনি আমাকে জিজ্ঞাসা করেন, যদি আপনার কাছে এমন কোনও কোডবেস রয়েছে যা মার্জিত উপায়ে ব্যতিক্রম হ্যান্ডলিং থেকে সত্যিই উপকৃত হয় তবে এর সর্বনিম্ন সংখ্যার catchব্লক থাকা উচিত (নূন্যতম দ্বারা আমি শূন্য নয়, তবে প্রতিটি অনন্য হাই- শেষ ব্যবহারকারীর ক্রিয়াকলাপ যা ব্যর্থ হতে পারে এবং সমস্ত উচ্চ-ব্যবহারকারীর ক্রিয়াকলাপ কেন্দ্রীয় কমান্ড সিস্টেমের মাধ্যমে আহ্বান করা হলেও সম্ভবত কম))

রিসোর্স ক্লিনআপ

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

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

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

বাহ্যিক পার্শ্ব প্রতিক্রিয়া বিপরীত

এই সমাধানের জন্য সবচেয়ে কঠিন ধারণাগত সমস্যা। যদি কোনও ক্রিয়াকলাপ, এটি কোনও ত্রুটি প্রচারক বা ব্যর্থতার বিন্দু বাহ্যিক পার্শ্ব প্রতিক্রিয়া সৃষ্টি করে, তবে সিস্টেমটিকে একটি অবস্থায় ফিরিয়ে আনার জন্য সেই পার্শ্ব প্রতিক্রিয়াগুলি "পূর্বাবস্থায়িত" করা দরকার যদিও অপারেশনটি কখনও ঘটেনি, " অর্ধ-বৈধ "রাষ্ট্র যেখানে অর্ধেক অভিযান সফল হয়েছিল। আমি এমন কোন ভাষা সম্পর্কে জানি না যা এই ধারণাগত সমস্যাটিকে আরও সহজ করে তোলে এমন ভাষা ব্যতীত যেগুলি প্রথমে বাহ্যিক পার্শ্ব প্রতিক্রিয়া সৃষ্টি করার জন্য বেশিরভাগ ফাংশনের প্রয়োজনকে কমিয়ে দেয়, যেমন কার্যকরী ভাষাগুলি যা অপরিবর্তনীয়তা এবং অবিরাম ডাটা স্ট্রাকচারের চারদিকে ঘোরে।

এখানে finally, সেখানে পরিবর্তনশীলতা এবং পার্শ্ব প্রতিক্রিয়া চারপাশে ঘুরপাক ভাষায় সমস্যার সবচেয়ে মার্জিত সমাধান মধ্যে তর্কসাপেক্ষে কারণ প্রায়ই যুক্তিবিজ্ঞান এই ধরনের একটি নির্দিষ্ট ফাংশন খুব নির্দিষ্ট এবং "রিসোর্স পরিষ্করণ ধারণা থেকে এত ভাল মানচিত্র নেই "। finallyআপনার এই catchব্লকটি দরকার কিনা তা বিবেচনা না করেই আপনার ফাংশনটি সমর্থন করে এমন ভাষাগুলিতে পার্শ্ব প্রতিক্রিয়াগুলির বিপরীত হয়েছে কিনা তা নিশ্চিত করার জন্য আমি এই ক্ষেত্রে উদারভাবে ব্যবহার করার পরামর্শ দিচ্ছি (এবং আবার, আপনি যদি আমাকে জিজ্ঞাসা করেন, ভাল লিখিত কোডের ন্যূনতম সংখ্যার সংখ্যা থাকতে হবে) catchব্লকগুলি এবং সমস্ত catchব্লক এমন জায়গাগুলিতে হওয়া উচিত যেখানে এটি উপরের চিত্রের সাথে সর্বাধিক অর্থবোধ করে Load Image User Command)।

স্বপ্নের ভাষা

যাইহোক, আইএমও finallyপার্শ্ব প্রতিক্রিয়া বিপরীতের জন্য আদর্শের কাছাকাছি তবে বেশ নয়। booleanঅকাল প্রস্থান (নিক্ষিপ্ত ব্যতিক্রম বা অন্যথায়) এর ক্ষেত্রে পার্শ্ব প্রতিক্রিয়াগুলি কার্যকরভাবে পিছনে রোল করতে আমাদের একটি পরিবর্তনশীল প্রবর্তন করতে হবে :

bool finished = false;
try
{
    // Cause external side effects.
    ...

    // Indicate that all the external side effects were
    // made successfully.
    finished = true; 
}
finally
{
    // If the function prematurely exited before finishing
    // causing all of its side effects, whether as a result of
    // an early 'return' statement or an exception, undo the
    // side effects.
    if (!finished)
    {
        // Undo side effects.
        ...
    }
}

আমি যদি কোনও ভাষা ডিজাইন করতে পারি তবে এই সমস্যাটি সমাধানের আমার স্বপ্নের উপায়টি উপরের কোডটি স্বয়ংক্রিয় করার মতো হবে:

transaction
{
    // Cause external side effects.
    ...
}
rollback
{
    // This block is only executed if the above 'transaction'
    // block didn't reach its end, either as a result of a premature
    // 'return' or an exception.

    // Undo side effects.
    ...
}

... স্থানীয় সম্পদের পরিচ্ছন্নতা স্বয়ংক্রিয় করার জন্য ধ্বংসকারীদের সাথে এটি তৈরি করা যাতে আমাদের কেবল প্রয়োজন হয় transaction, rollbackএবং catch(যদিও আমি এখনও finallyসি সংস্থানগুলির সাথে নিজেকে যুক্ত করতে চাই না বলে যুক্ত করতে চাই)। যাইহোক, finallyএকটি booleanভেরিয়েবলের সাথে এটিকে সোজা করে তোলার সবচেয়ে কাছের জিনিসটি আমি এখনও পর্যন্ত আমার স্বপ্নের ভাষার অভাব পেয়েছি। এর জন্য দ্বিতীয় দ্বিতীয়টি সহজ সমাধান আমি পেয়েছি সি ++ এবং ডি এর মতো ভাষাগুলির স্কোপ গার্ড , তবে আমি সর্বদা স্কোপ গার্ডদেরকে ধারণা থেকে খানিকটা বিশ্রী দেখতে পাই যেহেতু এটি "রিসোর্স ক্লিনআপ" এবং "পার্শ্ব প্রতিক্রিয়া বিপরীত" ধারণাটিকে ঝাপসা করে। আমার মতে এগুলি খুব আলাদা ধারণা যা আলাদাভাবে মোকাবেলা করতে হবে।

কোনও ভাষার আমার ছোট পাইপ স্বপ্নটি অপরিবর্তনযোগ্যতা এবং অবিচ্ছিন্ন ডাটা স্ট্রাকচারের চারপাশে প্রচুর পরিমাণে ঘুরে বেড়াত যাতে প্রয়োজনীয় না হলেও দক্ষ কার্যকরী রচনার জন্য যা কার্যকরী কারণে সত্ত্বেও বৃহত্তর ডেটা স্ট্রাকচারকে গভীরভাবে অনুলিপি করতে হয় না। কোন পার্শ্ব প্রতিক্রিয়া।

উপসংহার

যাইহোক যাইহোক, আমার রামফুলগুলি একপাশে রেখে, আমি মনে করি try/finallyযে সকেটটি বন্ধ করার জন্য আপনার কোডটি দুর্দান্ত এবং দুর্দান্ত তা বিবেচনা করে যে পাইথনের সিস্ট্রিক্ট ডিস্ট্রাস্টারগুলির সমতুল্য নেই, এবং আমি ব্যক্তিগতভাবে মনে করি যে সেই জায়গাগুলির জন্য আপনার সেই উদারভাবে ব্যবহার করা উচিত যা পার্শ্ব প্রতিক্রিয়াগুলি বিপরীতমুখী করতে হবে need এবং আপনাকে catchযে জায়গাগুলি সর্বাধিক বোধগম্য করতে হবে সেখানে যে সংখ্যাগুলি হ্রাস করতে হবে।


-66

ত্রুটিগুলি / ব্যতিক্রমগুলি ধরা এবং এগুলিকে ঝরঝরে করে পরিচালনা করা বাধ্যতামূলক না হলেও চূড়ান্তভাবে সুপারিশ করা হয়।

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

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

সুবর্ণ নিয়ম: সর্বদা ব্যতিক্রম ধরা, কারণ অনুমান করতে সময় লাগে


22
-১: জাভাতে, সংস্থানগুলি ছেড়ে দেওয়ার জন্য শেষ অবধি প্রয়োজন হতে পারে (যেমন কোনও ফাইল বন্ধ করুন বা একটি ডিবি সংযোগ প্রকাশ করুন)। এটি একটি ব্যতিক্রম পরিচালনা করার ক্ষমতা থেকে স্বাধীন।
কেভিন ক্লায়ান

@ কেভিঙ্কলাইন, তিনি অবশেষে ব্যবহার করবেন কিনা তা জিজ্ঞাসা করছেন না ... ব্যতিক্রম ধরার দরকার আছে কিনা তা তিনি কেবলই জিজ্ঞাসা করছেন .... চেষ্টা, ধর এবং শেষ পর্যন্ত কী করে সে জানে ..... শেষ পর্যন্ত অতি প্রয়োজনীয় অংশটি, আমরা সকলেই জানি এবং এটি কেন ব্যবহার করা হয় ....
পঙ্কজ উপাধ্যায়

63
@ পঙ্কজ: আপনার উত্তর থেকে জানা যায় যে catchযখনই কোন শর্ত থাকে তখন একটি ধারা সর্বদা উপস্থিত থাকা উচিত try। আমাকে সহ আরও অভিজ্ঞ অবদানকারীরা বিশ্বাস করেন যে এটি খারাপ পরামর্শ। আপনার যুক্তি ত্রুটিযুক্ত। এই পদ্ধতিটি ধারণ করে কেবল tryব্যতিক্রম ধরা যায় place কোডটিতে ক্যাচ ক্লজগুলি নকল করার চেয়ে শীর্ষ-স্তরের ব্যতিক্রমগুলি ধরা ও রিপোর্ট করতে মঞ্জুরি দেওয়া প্রায়শই সহজ এবং সেরা।
কেভিন লাইভ

@ কেভিঙ্কলাইন, আমি বিশ্বাস করি যে অন্যদের বিষয়ে প্রশ্নের ধারণাটি কিছুটা আলাদা। প্রশ্নটি ছিল যথাযথভাবে, আমরা কি একটি ব্যতিক্রম ধরা উচিত বা না .... এবং আমি সে বিষয়ে জবাব দিয়েছি। হ্যান্ডলিং এক্সসসেপশন কেবলমাত্র শেষ পর্যন্ত চেষ্টা করে নয় বিভিন্ন উপায়ে করা যেতে পারে। তবে, ওপির বিষয়টি উদ্বেগের বিষয় ছিল না। যদি আপনার এবং অন্যান্য ছেলেরা একটি ব্যতিক্রম উত্থাপন যথেষ্ট ভাল হয়, তবে আমি অবশ্যই ভাগ্য ভাল বলতে হবে।
পঙ্কজ উপাধ্যায়

ব্যতিক্রম সহ, আপনি চান যে বিবৃতিগুলির সাধারণ সম্পাদন বাধাগ্রস্থ হোক (এবং প্রতিটি পদক্ষেপে ম্যানুয়ালি সাফল্যের জন্য পরীক্ষা না করে)। এটি বিশেষত গভীরভাবে নেস্টেড পদ্ধতি কলগুলির ক্ষেত্রে - কিছু গ্রন্থাগারের ভিতরে একটি পদ্ধতি 4 স্তর কেবল একটি ব্যতিক্রম "গ্রাস" করতে পারে না; এটিকে সমস্ত স্তরগুলির মধ্য দিয়ে পিছনে ফেলে দেওয়া দরকার। অবশ্যই, প্রতিটি স্তর ব্যতিক্রম মোড়ানো এবং অতিরিক্ত তথ্য যুক্ত করতে পারে; এটি প্রায়শই বিভিন্ন কারণে করা হয় না, বাড়ার জন্য অতিরিক্ত সময় এবং অপ্রয়োজনীয় ভারবোসিটি দুটি সবচেয়ে বড় হয়ে থাকে।
ড্যানিয়েল বি
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.