आप उच्च स्तर पर नहीं सोच रहे हैं। ठीक है, निर्माता विफल रहता है। विशेषता अपरिभाषित बनी हुई है। लेकिन एक्सेसर को कॉल करने वाले कोड के बारे में आप क्या करते हैं? वर्ग के अनुबंध ने इंगित किया कि विधि को कॉल करना हमेशा आईओ :: फाइल लौटाएगा। लेकिन अब यह वापस आ रहा है। (अनुबंध IO::File
, नहीं Maybe[IO::File]
, सही था?)
तो कोड की अगली पंक्ति पर, फोन करने वाले मरने के लिए ("the_caller.pl लाइन 42 पर एक अपरिभाषित मूल्य पर विधि 'ReadLine' कॉल नहीं कर सकता जा रहा है "), क्योंकि यह अपेक्षा करता है कि आपकी कक्षा उस अनुबंध का पालन करे जो इसे परिभाषित करती है। विफलता कुछ ऐसा नहीं था जो आपकी कक्षा को करना था, लेकिन अब यह हुआ। कॉलर इस समस्या को ठीक करने के लिए कुछ भी कैसे कर सकता है?
यदि यह undef
को संभाल सकता है, तो कॉलर को वास्तव में फ़ाइलहेडल की शुरुआत करने की आवश्यकता नहीं थी ... तो यह आपके ऑब्जेक्ट को एक के लिए क्यों पूछता था?
इस बात को ध्यान में रखते हुए, केवल सायन समाधान मरना है। आप जिस अनुबंध से सहमत हैं, उससे आप नहीं मिल सकते हैं, और die
एकमात्र तरीका है जिससे आप उस स्थिति से बाहर निकल सकते हैं। तो बस यह करो; मृत्यु जीवन का एक तथ्य है।
अब, यदि आप निर्माता बनने पर मरने के लिए तैयार नहीं हैं, तो कोड को विफल करने के दौरान आपको बदलना होगा। आप ऑब्जेक्ट-निर्माण समय पर इसे या तो आलसी बनाकर, या स्पष्ट रूप से BUILD (BUILD { $self->file_name }
) में विशेषता को जीवंत बनाकर कर सकते हैं।
एक बेहतर विकल्प बिल्कुल बाहर की दुनिया से फ़ाइल हैंडल का खुलासा नहीं करने के लिए, और बदले की तरह कुछ करना है:
# dies when it can't write to the log file
method write_log {
use autodie ':file'; # you want "say" to die when the disk runs out of space, right?
my $fh = $self->file_handle;
say {$fh} $_ for $self->log_messages;
}
अब आप जानते हैं जब कार्यक्रम मरने के लिए जा रहा है; new
में, या write_log
में। आप जानते हैं क्योंकि दस्तावेज़ ऐसा कहते हैं।
दूसरा तरीका आपके कोड को बहुत साफ करता है; उपभोक्ता को आपकी कक्षा के कार्यान्वयन के बारे में जानने की आवश्यकता नहीं है, इसे सिर्फ यह जानना आवश्यक है कि यह कुछ लॉग संदेशों को लिखने के लिए कह सकता है। अब कॉलर आपके कार्यान्वयन के विवरण से चिंतित नहीं है; यह सिर्फ वर्ग को बताता है कि वह वास्तव में क्या करना चाहता था।
और write_log
में मरना कुछ भी हो सकता है जो आप (कैच ब्लॉक में) से पुनर्प्राप्त कर सकते हैं, जबकि "इस यादृच्छिक अपारदर्शी चीज़ को नहीं खोल सका जिसे आपको किसी भी तरह से नहीं पता होना चाहिए" कॉलर को पुनर्प्राप्त करने के लिए बहुत कठिन है से।
असल में, अपने कोड को स्वच्छ रूप से डिज़ाइन करें, और अपवाद ही एकमात्र उत्तर हैं।
(मुझे पूरा नहीं मिलता है "वे एक क्लेज हैं" वैसे भी। वे सी ++ में समान तरीके से काम करते हैं और जावा और हास्केल और इसी तरह की दूसरी भाषा में भी इसी तरह काम करते हैं। क्या die
शब्द वास्तव में डरावना या कुछ है?)
क्यों न केवल अपवाद फेंक दें? – friedo
@friedo, कृपया इस मामले में अपवादों को कैसे संभालेंगे इस पर विस्तृत करें। मेरी चिंता यह है कि अगर मैं बिल्डर में घातक अपवाद फेंकता हूं, तो इसका मतलब है कि जब भी मैं 'file_handle' तक पहुंचता हूं, तो मुझे अपवाद पकड़ने के लिए तैयार रहना होगा। – daotoad
यदि आपके पास कोई अपवाद नहीं है तो आपको यह जांचना होगा कि आप क्या लौटते हैं और कुछ विफल होने पर कुछ अलग करते हैं - अपवाद की जांच करना शायद कम कोड है। – Mark