আমি বলব, এপিআই একটি সম্পূর্ণতা হ্যান্ডলার সরবরাহ করে বা সাফল্য / ব্যর্থতা ব্লকগুলির জুড়ি দেয় কিনা তা মূলত ব্যক্তিগত পছন্দের বিষয়।
উভয় পদ্ধতিরই উপকারিতা এবং বোধ রয়েছে, যদিও কেবল সামান্য পার্থক্য রয়েছে।
আরও আরও বৈকল্পিক রয়েছে তা বিবেচনা করুন, উদাহরণস্বরূপ যেখানে এক সম্পূর্ণ হওয়ার হ্যান্ডলারটির কেবলমাত্র পরিণতি বা কোনও সম্ভাব্য ত্রুটির সমন্বয়ে কেবলমাত্র একটি প্যারামিটার থাকতে পারে :
typedef void (^completion_t)(id result);
- (void) taskWithCompletion:(completion_t)completionHandler;
[self taskWithCompletion:^(id result){
if ([result isKindOfError:[NSError class]) {
NSLog(@"Error: %@", result);
}
else {
...
}
}];
এই স্বাক্ষরটির উদ্দেশ্য হ'ল একটি সমাপ্তি হ্যান্ডলারটি অন্য এপিআইতে সাধারণভাবে ব্যবহার করা যায়।
উদাহরণস্বরূপ এনএসএর্রের জন্য বিভাগে একটি পদ্ধতি রয়েছে forEachApplyTask:completion:
যা ক্রমান্বয়ে প্রতিটি বস্তুর জন্য একটি কার্য ডাকে এবং লুপটি ভেঙে দেয় যদি ত্রুটি ঘটেছিল। যেহেতু এই পদ্ধতিটি নিজেও অবিচ্ছিন্ন, তাই এটির একটি সমাপ্তি হ্যান্ডলারও রয়েছে:
typedef void (^completion_t)(id result);
typedef void (^task_t)(id input, completion_t);
- (void) forEachApplyTask:(task_t)task completion:(completion_t);
প্রকৃতপক্ষে, completion_t
উপরে বর্ণিত হিসাবে সাধারণভাবে যথেষ্ট এবং সমস্ত পরিস্থিতিতে পরিচালনা করতে যথেষ্ট।
তবে কল-সাইটে এর সমাপ্তির বিজ্ঞপ্তিটি সংকেত দেওয়ার জন্য একটি অ্যাসিঙ্ক্রোনাস টাস্কের অন্যান্য উপায় রয়েছে:
অঙ্গীকার
প্রতিশ্রুতি, যাকে "ফিউচার", "ডিফার্ড" বা "বিলম্বিত" বলা হয় একটি অ্যাসিনক্রোনাস টাস্কের পরিণামের প্রতিনিধিত্ব করে (আরও দেখুন: উইকি ফিউচার এবং প্রতিশ্রুতি )।
প্রাথমিকভাবে, একটি প্রতিশ্রুতি "মুলতুবি" অবস্থায় রয়েছে। অর্থাৎ এটির "মান" এখনও মূল্যায়ন করা হয়নি এবং এখনও পাওয়া যায় নি।
অবজেক্টিভ-সি-তে, প্রতিশ্রুতিবদ্ধ হ'ল একটি সাধারণ অবজেক্ট যা নীচে প্রদর্শিত হিসাবে অ্যাসিক্রোনাস পদ্ধতি থেকে ফিরে আসবে:
- (Promise*) doSomethingAsync;
! প্রতিশ্রুতির প্রাথমিক অবস্থা "মুলতুবি"।
ইতিমধ্যে, অ্যাসিক্রোনাস কাজগুলি তার ফলাফলটি মূল্যায়ন করতে শুরু করে।
আরও মনে রাখবেন, কোনও সমাপ্তি হ্যান্ডলার নেই। পরিবর্তে, প্রতিশ্রুতি আরও শক্তিশালী উপায় সরবরাহ করবে যেখানে কল-সাইট অ্যাসিনক্রোনাস টাস্কের পরিণামটি পেতে পারে, যা আমরা শীঘ্রই দেখতে পাব।
অ্যাসিক্রোনাস টাস্ক, যা প্রতিশ্রুতি বস্তু তৈরি করেছিল, শেষ পর্যন্ত এর প্রতিশ্রুতি "সংকল্প" করা আবশ্যক। এর অর্থ, যেহেতু কোনও কাজ সফল হয় বা ব্যর্থ হতে পারে, তাই এটি মূল্যায়নকৃত ফলাফলটি পাস করার একটি প্রতিশ্রুতি "পূরণ" করতে হবে, বা ব্যর্থতার কারণকে নির্দেশ করে একটি ত্রুটি পাস করার প্রতিশ্রুতি "প্রত্যাখ্যান" করা আবশ্যক।
! একটি কাজ শেষ পর্যন্ত তার প্রতিশ্রুতি সমাধান করতে হবে।
যখন কোনও প্রতিশ্রুতি সমাধান করা হয়, তখন এর মান সহ এটি আর রাষ্ট্রের পরিবর্তন করতে পারে না।
! একটি প্রতিশ্রুতি কেবল একবার সমাধান করা যেতে পারে ।
প্রতিশ্রুতি একবার সমাধান হয়ে গেলে, কোনও কল-সাইট ফলাফল অর্জন করতে পারে (তা ব্যর্থ হোক বা সফল হোক)। কীভাবে এটি সম্পাদন করা হয় তা নির্ভর করে সিঙ্ক্রোনাস বা অ্যাসিঙ্ক্রোনাস স্টাইল ব্যবহার করে প্রতিশ্রুতি বাস্তবায়ন করা হয়।
একটি প্রতিশ্রুতি পারেন করার জন্য একটি সমলয় অথবা একটি অ্যাসিঙ্ক্রোনাস শৈলী যেখানে বিশালাকার বাস্তবায়িত করা যাবে ব্লক যথাক্রমে অ ব্লক শব্দার্থবিদ্যা।
প্রতিশ্রুতির মান পুনরুদ্ধার করার জন্য একটি সিঙ্ক্রোনাস স্টাইলে, একটি কল-সাইট এমন একটি পদ্ধতি ব্যবহার করবে যা বর্তমান থ্রেডকে অ্যাসিঙ্ক্রোনাস টাস্ক দ্বারা প্রতিশ্রুতি সমাধান না করা এবং পরিণাম প্রাপ্ত ফলাফল প্রাপ্ত হওয়া অবধি অবরুদ্ধ করবে ।
অ্যাসিঙ্ক্রোনাস স্টাইলে, কল-সাইট কলব্যাকগুলি বা হ্যান্ডলার ব্লকগুলি নিবন্ধভুক্ত করবে যা প্রতিশ্রুতি সমাধানের সাথে সাথে কল হয়ে যায়।
এটি প্রমাণিত হয়েছে যে সিঙ্ক্রোনাস স্টাইলে বেশ কয়েকটি উল্লেখযোগ্য অসুবিধা রয়েছে যা কার্যকরভাবে অ্যাসিঙ্ক্রোনাস টাস্কগুলির গুণাবলীকে পরাভূত করে। স্ট্যান্ডার্ড সি ++ 11 লাইবটিতে বর্তমানে "ফিউচার" এর ত্রুটিযুক্ত বাস্তবায়ন সম্পর্কে একটি আকর্ষণীয় নিবন্ধটি এখানে পড়তে পারেন: ভাঙা প্রতিশ্রুতি – C ++ 0x ফিউচার ।
কীভাবে, উদ্দেশ্য-সি-তে, কোনও কল-সাইট ফলাফল অর্জন করবে?
ভাল, কয়েকটি উদাহরণ প্রদর্শন করা ভাল। এখানে দুটি পাঠাগার রয়েছে যা একটি প্রতিশ্রুতি বাস্তবায়ন করে (নীচের লিঙ্কগুলি দেখুন)।
তবে, পরবর্তী কোড স্নিপেটের জন্য, আমি গিটহাব আরএক্সপ্রোমিতে উপলব্ধ একটি প্রতিশ্রুতি পাঠাগারটির একটি বিশেষ প্রয়োগ ব্যবহার করব । আমি আরএক্সপ্রোমাইজের লেখক।
অন্যান্য বাস্তবায়নের অনুরূপ এপিআই থাকতে পারে তবে সিনট্যাক্সে ছোট এবং সম্ভবত সূক্ষ্ম পার্থক্য থাকতে পারে। আরএক্সপ্রাইম হ'ল প্রতিশ্রুতি / এ + নির্দিষ্টকরণের একটি উদ্দেশ্য-সি সংস্করণ যা জাভাস্ক্রিপ্টে প্রতিশ্রুতিগুলির মজবুত এবং আন্তঃব্যবহারযোগ্য প্রয়োগের জন্য একটি মুক্ত মান নির্ধারণ করে।
নীচে তালিকাভুক্ত সমস্ত প্রতিশ্রুতি পাঠাগারগুলি অ্যাসিঙ্ক্রোনাস শৈলী বাস্তবায়ন করে।
বিভিন্ন বাস্তবায়নের মধ্যে বেশ উল্লেখযোগ্য পার্থক্য রয়েছে। আরএক্সপ্রাইম অভ্যন্তরীণরূপে প্রেরণার লিবিব ব্যবহার করে, পুরোপুরি থ্রেড নিরাপদ, অত্যন্ত হালকা ওজনের, এবং বাতিল করার মতো অনেকগুলি অতিরিক্ত দরকারী বৈশিষ্ট্যও সরবরাহ করে।
একটি কল-সাইট হ্যান্ডলারের "নিবন্ধকরণ" এর মাধ্যমে অ্যাসিনক্রোনাস টাস্কের শেষ ফলাফল প্রাপ্ত করে। "প্রতিশ্রুতি / এ + নির্দিষ্টকরণ" পদ্ধতিটি সংজ্ঞায়িত করে then
।
পদ্ধতি then
আরএক্সপ্রাইজ সহ এটি নীচের মত দেখাচ্ছে:
promise.then(successHandler, errorHandler);
যেখানে সাফল্য হ্যান্ডলার এমন একটি ব্লক যা যখন প্রতিশ্রুতিটি " বাস্তবায়ন " হয়ে যায় এবং ত্রুটিহ্যান্ডলার এমন একটি ব্লক যা যখন প্রতিশ্রুতি "প্রত্যাখ্যান" হয়ে যায় তখন ডাকে।
! then
চূড়ান্ত ফলাফল পেতে এবং একটি সাফল্য বা একটি ত্রুটি হ্যান্ডলার সংজ্ঞায়িত করতে ব্যবহৃত হয়।
আরএক্সপ্রাইমে হ্যান্ডলার ব্লকের নীচে স্বাক্ষর রয়েছে:
typedef id (^success_handler_t)(id result);
typedef id (^error_handler_t)(NSError* error);
সাফল্য_হ্যান্ডলারের একটি প্যারামিটার ফলাফল রয়েছে যা স্পষ্টতই অ্যাসিনক্রোনাস টাস্কের পরিণাম। তেমনি, ত্রুটি- হ্যান্ডলারের একটি প্যারামিটার ত্রুটি থাকে যা এটি ব্যর্থ হওয়ার পরে অ্যাসিক্রোনাস টাস্ক দ্বারা রিপোর্ট করা ত্রুটি।
উভয় ব্লকের একটি ফেরতের মান রয়েছে। এই রিটার্নের মান কী, তা শিগগিরই পরিষ্কার হয়ে যাবে।
আরএক্সপ্রোমিতে, then
এমন একটি সম্পত্তি যা একটি ব্লক দেয়। এই ব্লকের দুটি পরামিতি রয়েছে, সাফল্য হ্যান্ডলার ব্লক এবং ত্রুটি হ্যান্ডলার ব্লক। হ্যান্ডলারগুলি অবশ্যই কল-সাইট দ্বারা সংজ্ঞায়িত করা উচিত।
! হ্যান্ডলারগুলি অবশ্যই কল-সাইট দ্বারা সংজ্ঞায়িত করা উচিত।
সুতরাং, অভিব্যক্তি promise.then(success_handler, error_handler);
একটি সংক্ষিপ্ত রূপ
then_block_t block promise.then;
block(success_handler, error_handler);
আমরা আরও বেশি সংক্ষিপ্ত কোড লিখতে পারি:
doSomethingAsync
.then(^id(id result){
…
return @“OK”;
}, nil);
কোডটিতে লেখা আছে: "doSomethingAsync কার্যকর করুন, যখন এটি সফল হয়, তারপরে সাফল্য হ্যান্ডলার কার্যকর করুন"।
এখানে, ত্রুটি হ্যান্ডলারটি nil
যার অর্থ, কোনও ত্রুটির ক্ষেত্রে, এটি এই প্রতিশ্রুতিতে পরিচালিত হবে না।
আর একটি গুরুত্বপূর্ণ বিষয় হ'ল সম্পত্তি থেকে ফিরে আসা ব্লকটি কল করা then
একটি প্রতিশ্রুতি ফিরিয়ে দেবে:
! then(...)
প্রতিশ্রুতি দেয়
সম্পত্তি থেকে ফিরে আসা ব্লকটি কল করার সময় then
, "রিসিভার" একটি নতুন প্রতিশ্রুতি দেয়, সন্তানের প্রতিশ্রুতি। গ্রহীতা পিতামাতার প্রতিশ্রুতি হয়ে ওঠে ।
RXPromise* rootPromise = asyncA();
RXPromise* childPromise = rootPromise.then(successHandler, nil);
assert(childPromise.parent == rootPromise);
ওটার মানে কি?
ঠিক আছে, এর কারণে আমরা অ্যাসিঙ্ক্রোনাস কাজগুলিকে কার্যকরভাবে ক্রমান্বয়ে কার্যকর করতে পারি "চেইন" করতে পারি।
তদ্ব্যতীত, উভয়ই হ্যান্ডলারের ফেরতের মান প্রত্যাশিত প্রতিশ্রুতির "মান" হয়ে উঠবে। সুতরাং, যদি কাজটি শেষ ফলাফল @ "ঠিক আছে" দিয়ে সফল হয় তবে প্রত্যাবর্তিত প্রতিশ্রুতি "" ঠিক আছে "মান সহ" সমাধান "হবে (এটি" পরিপূর্ণ ") হবে:
RXPromise* returnedPromise = asyncA().then(^id(id result){
return @"OK";
}, nil);
...
assert([[returnedPromise get] isEqualToString:@"OK"]);
তেমনিভাবে, যখন অ্যাসিক্রোনাস টাস্ক ব্যর্থ হয়, প্রত্যাবর্তিত প্রতিশ্রুতি একটি ত্রুটি সহ সমাধান করা হবে (এটি "প্রত্যাখ্যানিত")।
RXPromise* returnedPromise = asyncA().then(nil, ^id(NSError* error){
return error;
});
...
assert([[returnedPromise get] isKindOfClass:[NSError class]]);
হ্যান্ডলার এছাড়াও অন্য প্রতিশ্রুতি ফিরে আসতে পারে। উদাহরণস্বরূপ যখন সেই হ্যান্ডলারটি অন্য একটি অ্যাসিনক্রোনাস টাস্ক কার্যকর করে। এই প্রক্রিয়াটির সাহায্যে আমরা অবিচ্ছিন্ন কাজগুলি "চেইন" করতে পারি:
RXPromise* returnedPromise = asyncA().then(^id(id result){
return asyncB(result);
}, nil);
! একটি হ্যান্ডলার ব্লকের রিটার্ন মান শিশুর প্রতিশ্রুতির মান হয়ে যায়।
যদি কোনও সন্তানের প্রতিশ্রুতি না থাকে তবে রিটার্ন মানটির কোনও প্রভাব নেই।
আরও জটিল উদাহরণ:
এখানে, আমরা চালানো asyncTaskA
, asyncTaskB
, asyncTaskC
এবং asyncTaskD
ক্রমানুসারে - এবং প্রতিটি পরবর্তী কাজের ইনপুট হিসাবে পূর্ববর্তী কাজের ফল লাগে:
asyncTaskA()
.then(^id(id result){
return asyncTaskB(result);
}, nil)
.then(^id(id result){
return asyncTaskC(result);
}, nil)
.then(^id(id result){
return asyncTaskD(result);
}, nil)
.then(^id(id result){
// handle result
return nil;
}, nil);
এই জাতীয় "চেইন" কে "ধারাবাহিকতা" বলা হয়।
ত্রুটি পরিচালনা
প্রতিশ্রুতিগুলি ত্রুটিগুলি পরিচালনা করা বিশেষত সহজ করে তোলে। পিতামাতার প্রতিশ্রুতিতে কোনও ত্রুটি হ্যান্ডলার সংজ্ঞায়িত না হলে ত্রুটিগুলি পিতামাতার কাছ থেকে সন্তানের কাছে "ফরোয়ার্ড" করা হবে। কোনও শিশু এটি পরিচালনা না করা অবধি ত্রুটিটি চেইন আপ করা হবে। সুতরাং, উপরের চেইনটি থাকাতে, আমরা কেবলমাত্র অন্য একটি "ধারাবাহিকতা" যুক্ত করে ত্রুটি পরিচালনার প্রয়োগ করতে পারি যা কোনও সম্ভাব্য ত্রুটি যা উপরের যে কোনও জায়গায় ঘটতে পারে তা নিয়ে কাজ করে :
asyncTaskA()
.then(^id(id result){
return asyncTaskB(result);
}, nil)
.then(^id(id result){
return asyncTaskC(result);
}, nil)
.then(^id(id result){
return asyncTaskD(result);
}, nil)
.then(^id(id result){
// handle result
return nil;
}, nil);
.then(nil, ^id(NSError*error) {
NSLog(@“”Error: %@“, error);
return nil;
});
এটি ব্যতিক্রম হ্যান্ডলিংয়ের সাথে সম্ভবত আরও পরিচিত সিনক্রোনাস স্টাইলের অনুরূপ:
try {
id a = A();
id b = B(a);
id c = C(b);
id d = D(c);
// handle d
}
catch (NSError* error) {
NSLog(@“”Error: %@“, error);
}
প্রতিশ্রুতি সাধারণভাবে অন্যান্য দরকারী বৈশিষ্ট্য রয়েছে:
উদাহরণস্বরূপ, একটি প্রতিশ্রুতির রেফারেন্স থাকা, then
একজনের মাধ্যমে যতগুলি হ্যান্ডলারগুলি পছন্দসইভাবে "নিবন্ধন" করতে পারেন। আরএক্সপ্রাইজে, হ্যান্ডলারদের নিবন্ধকরণ যে কোনও সময় এবং যে কোনও থ্রেড থেকে ঘটতে পারে যেহেতু এটি পুরোপুরি থ্রেড-নিরাপদ।
আরএক্সপ্রোমিসে আরও বেশ কয়েকটি কার্যকর কার্যকরী বৈশিষ্ট্য রয়েছে, প্রতিশ্রুতি / এ + নির্দিষ্টকরণের প্রয়োজন হয় না। একটি হ'ল "বাতিলকরণ"।
দেখা গেল যে "বাতিলকরণ" একটি অমূল্য এবং গুরুত্বপূর্ণ বৈশিষ্ট্য। উদাহরণস্বরূপ, কোনও প্রতিশ্রুতির রেফারেন্স সহ একটি কল-সাইট এটি cancel
বার্তাটি প্রেরণ করতে পারে যাতে এটি শেষের ফলাফলের জন্য আর আগ্রহী না।
কেবলমাত্র একটি অ্যাসিক্রোনাস টাস্কের কল্পনা করুন যা ওয়েব থেকে কোনও চিত্র লোড করে এবং যা একটি ভিউ কন্ট্রোলারে প্রদর্শিত হবে। ব্যবহারকারী যদি বর্তমান ভিউ কন্ট্রোলার থেকে দূরে সরে যায় তবে বিকাশকারী কোডটি প্রয়োগ করতে পারে যা চিত্রপ্রোমে একটি বাতিল বার্তা প্রেরণ করে , যার ফলে এইচটিটিপি অনুরোধ অপারেশন দ্বারা সংজ্ঞায়িত ত্রুটি হ্যান্ডলারটিকে ট্রিগার করে যেখানে অনুরোধটি বাতিল হয়ে যাবে।
আরএক্সপ্রাইমে, একটি বাতিল বার্তা কেবলমাত্র তার পিতামাতার কাছ থেকে তার বাচ্চাদের কাছে পাঠানো হবে, তবে তদ্বিপরীত নয়। এটি, একটি "মূল" প্রতিশ্রুতি সমস্ত বাচ্চার প্রতিশ্রুতি বাতিল করে দেবে। তবে সন্তানের প্রতিশ্রুতি কেবল সেই "শাখা" বাতিল করবে যেখানে এটি পিতামাতা। যদি কোনও প্রতিশ্রুতি ইতিমধ্যে সমাধান হয়ে যায় তবে বাতিল বার্তাটি বাচ্চাদের কাছেও পাঠানো হবে।
একটি অ্যাসিঙ্ক্রোনাস টাস্ক নিজেই নিজের প্রতিশ্রুতির জন্য হ্যান্ডলার নিবন্ধন করতে পারে এবং অন্য কেউ কখন এটি বাতিল করে তা সনাক্ত করতে পারে। এরপরে এটি অসময়ে সম্ভবত একটি দীর্ঘ এবং ব্যয়বহুল কাজ সম্পাদন বন্ধ করে দিতে পারে।
এখানে গিটহাবের উপর পাওয়া উদ্দেশ্য-সি-র প্রতিশ্রুতির আরও কয়েকটি বাস্তবায়ন রয়েছে:
https://github.com/Schoonology/aplus-objc
https://github.com/affablebloke/deferred-objective-c
https://github.com/bww/FutureKit
https://github.com/jkubicek/JKPromises
https://github.com/Strilanc/ObjC- CollapsingFutures
https://github.com/b52/OMPromise
https://github.com/mproberts/objc-promise
https://github.com/klaaspieter/Promise
https: //github.com/jameswomack/Promise
https://github.com/nilfs/promise-objc
https://github.com/mxcl/PromiseKit
https://github.com/apleshkov/promises-aplus
https: // github.com/KptainO/Rebelle
এবং আমার নিজস্ব বাস্তবায়ন: আরএক্সপ্রোমাইজ ।
এই তালিকাটি সম্ভবত সম্পূর্ণ নয়!
আপনার প্রকল্পের জন্য কোনও তৃতীয় গ্রন্থাগার চয়ন করার সময়, দয়া করে লাইব্রেরির প্রয়োগটি নীচে তালিকাভুক্ত পূর্বশর্তগুলি অনুসরণ করে কিনা তা সাবধানতার সাথে পরীক্ষা করে দেখুন:
একটি নির্ভরযোগ্য প্রতিশ্রুতি গ্রন্থাগার থ্রেড নিরাপদ হবে!
এটি সমস্তই অ্যাসিনক্রোনাস প্রসেসিংয়ের বিষয়ে, এবং আমরা একাধিক সিপিইউ ব্যবহার করতে এবং যখনই সম্ভব সম্ভব বিভিন্ন থ্রেডে চালিত করতে চাই। সাবধান, বেশিরভাগ বাস্তবায়ন থ্রেড নিরাপদ নয়!
হ্যান্ডেলার বলে গন্য হবে অ্যাসিঙ্ক্রোনাস যা কল-সাইট থেকে সম্মান! সর্বদা, এবং যাই হোক না কেন!
অ্যাসিঙ্ক্রোনাস ফাংশনগুলি গ্রহণ করার সময় যে কোনও শালীন বাস্তবায়নও খুব কঠোর প্যাটার্ন অনুসরণ করা উচিত। অনেক বাস্তবায়নকারী কেসটিকে "অনুকূলিতকরণ" করতে ঝোঁকেন, যেখানে হ্যান্ডলারটি নিবন্ধিত হবে যখন প্রতিশ্রুতি ইতিমধ্যে সমাধান হয়ে গেছে তখন একটি হ্যান্ডলার সিঙ্ক্রোনসিভভাবে ডাকা হবে। এটি সব ধরণের সমস্যার কারণ হতে পারে। জালগো মুক্তি দিবেন না দেখুন ! ।
কোনও প্রতিশ্রুতি বাতিল করার ব্যবস্থাও থাকতে হবে।
অ্যাসিক্রোনাস টাস্ক বাতিল করার সম্ভাবনা প্রায়শই প্রয়োজনীয়তা বিশ্লেষণে উচ্চ অগ্রাধিকার সহ একটি প্রয়োজনীয়তা হয়ে ওঠে। যদি তা না হয় তবে অবশ্যই অ্যাপটি প্রকাশের পরে কিছুক্ষণ পরে কোনও ব্যবহারকারীর কাছ থেকে বর্ধনের অনুরোধ জানানো হবে। কারণটি সুস্পষ্ট হওয়া উচিত: যে কোনও কাজ স্টল বা শেষ হতে খুব বেশি সময় নিতে পারে, তা ব্যবহারকারী বা একটি সময়সীমা দ্বারা বাতিল করতে হবে। একটি শালীন প্রতিশ্রুতি গ্রন্থাগারের বাতিল সমর্থন করা উচিত।