2016-01-27 12 views
5

अजगर में, आप सूचकांक एक आउट-ऑफ-सीमा कुंजी/सूचकांक के साथ एक संग्रह संरचना, आप चेहरे पर एक थप्पड़ मिलता है:क्या मैं कृपया ArrayOutOfBoundsException कर सकता हूं?

>>> [1, 2, 3][9] 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
IndexError: list index out of range 

एक अपवाद है कि; यह बेसएक्सप्शन से निकला है, और एक को संभालने में असफल मेरे प्रोग्राम को क्रैश करेगा, जो लगभग हमेशा चाहता है।


पर्ल 5 और 6 की सूची अनुक्रमण के बारे में परवाह नहीं लगता है बाहर के सीमा अनुक्रमण:

$ perl6 
> my @l = (1..4); 
[1 2 3 4] 
> say @l[2]; 
3 
> say @l[9]; 
(Any) 
> print @l[9];                           
Use of uninitialized value @l of type Any in string context 
<snip>  
True 
> my $x = @l[9]; # even assignment doesn't error! who decided this was okay!? 
> say $x; print $x; 
(Any) 
Use of uninitialized value $x of type Any in string context 
<snip>  

यह मूल रूप से पर्ल 5 में एक ही बात है, को छोड़कर आप एक मूल्य नहीं मिलता है वापस आ गया, लेकिन निष्पादन सामान्य के रूप में जारी है।

मुझे समझ में नहीं आता कि क्यों बाहर की सीमाएं चुप होनी चाहिए। आपको वह मान प्राप्त करने वाली एकमात्र चेतावनियां "अनियंत्रित" हो सकती हैं (लेकिन हम सभी जानते हैं कि इसका अर्थ वास्तव में मौजूद नहीं है) जब आप इसे कुछ फ़ंक्शंस देते हैं।

क्या मैं इसे किसी भी तरह ठीक कर सकता हूं? मैं जंक इंडेक्स पर मरने वाले डिफ़ॉल्ट व्यक्ति को ओवरराइड करने के लिए अपने स्वयं के पोस्ट-सर्फिक्स इंडेक्सिंग ऑपरेटर को कार्यान्वित कर सकता हूं, लेकिन एक अनियमित मूल्य और Any टाइप के बीच अंतर बताने का कोई तरीका नहीं है। I ऐसा करने का एकमात्र तरीका यह जांचना है कि अनुरोधित अनुक्रमणिका List.elems() सीमा में है या नहीं।

क्या इसका उपयोग करने के लिए मैं (अधिमानतः न्यूनतम, सरल, साफ, पठनीय, आदि) समाधान का उपयोग कर सकता हूं?


किसी को भी करने से पहले कहते हैं, "हाँ, लेकिन चर my $x; तरह uninitialised है,!": आप स्मृति आप आवंटित नहीं किया का उपयोग करता है, तो सी में आप एक segfault मिलता है, मुझे ऐसी सुरक्षा क्यों नहीं मिल सकती है?


मैं दोनों पर्ल और पर्ल 6 के रूप में इस टैग किया है, क्योंकि जब मैं पर्ल 6 सीख रहा हूँ और इस सवाल का विवरण ज्यादातर 6 पर लागू होते हैं, मुख्य विचार दोनों 5 का एक साझा पहलू हो रहा है और 6.

+0

सी में सेगमेंटेशन गलती निष्पादन से बेहतर है जैसे कि कुछ भी नहीं हुआ। – cat

+2

पर्ल ऐसा करता है जो आप इससे पूछते हैं कि इससे कोई फर्क नहीं पड़ता। यह आपको लगता है कि आप क्या पूछ रहे हैं, यह वास्तव में कुछ भी नहीं मानता है। यह वास्तव में एक उड़ान छलांग नहीं दे सका अगर आप जानते हैं या चाहते हैं कि आप इसके लिए क्या पूछ रहे हैं तो यह आपको केवल देगा। यदि आप 'परिभाषित' की जांच करते हैं तो आपको क्रैच जैसे अपवादों का उपयोग करने की आवश्यकता नहीं है। असल में यह एक आदर्श बदलाव है और एक पायथन डेवलपर होने के नाते यह आलेख काफी अच्छी तरह से विचारों के अंतर को रेखांकित करता है: http://yosefk.com/blog/what-makes-cover-up-preferable-to-error-handling.html – scrappedcola

+0

@scrappedcola प्रतिक्रिया के लिए धन्यवाद! मुझे पता है, आप बता सकते हैं कि मैं पाइथोनिज्म से भरा हूं लेकिन मैं किसी अन्य भाषा के बारे में नहीं सोच सकता जहां यह दुर्घटना नहीं पैदा करेगा, क्योंकि सिर्फ कोई अन्य तार्किक प्रतिक्रिया नहीं है। – cat

उत्तर

11

पर्ल 6 ने सरल या बहुआयामी सरणी पर सरणी सीमाओं को लागू करने के लिए सरणी को आकार दिया है।

S09 से

:

my int @ints[4;2];   # Valid indices are 0..3 ; 0..1 
my @calendar[12;31;24];  # Valid indices are 0..11 ; 0..30 ; 0..23 

कुछ और उदाहरण:

use v6; 
# declare an array with four elements 
my @l[4] = (1..4); 
try { @l.push: 42} 
say @l; 
# [1 2 3 4] 

ये बहु-आयामी

my @tic_tac_toe[3;3] = <x o x>, <o . o>, < x o x>; 
@tic_tac_toe[1;1] = "x";  # ok 
try @tic_tac_toe[3][3] = "o"; # illegal 
say @tic_tac_toe; 
# [[x o x] [o x o] [x o x]] 
+0

अगर ऐसा होता है, तो ऐसा लगता है कि यह कैसे चला जाता है। – cat

-1

जो लगभग हमेशा जो मैं चाहता है हो सकता है।

कृपया अपने विचारों के लिए एक भाषा को अनुकूलित करने की कोशिश न करें, लेकिन अपने विचारों को भाषा में अनुकूलित करें। यदि आप ऐसा करने के इच्छुक नहीं हैं तो यह एक और भाषा का उपयोग करें जो आपके विचारों को फिट करे। यह एक बुरा विचार है कि पर्ल में जावा-स्टाइल कोड लिखने की कोशिश कर रहा है क्योंकि यह जावा में पर्ल-स्टाइल कोड लिखना होगा।

+5

"अपने विचारों में एक भाषा को अनुकूलित करने की कोशिश न करें" क्षमा करें, कारण है कि मैं कंप्यूटर को अपने विचारों में कंप्यूटर को अनुकूलित करना चाहता हूं, और कारण मुझे लगता है कि पर्ल 6 अच्छा है क्योंकि यह मेरे विचारों के लिए लचीला और अनुकूल है। – cat

+1

@cat: "... मुख्य विचार 5 और 6 दोनों की एक साझा दोष/सुविधा है।" - जाहिर है आप भाषा के बारे में शिकायत कर रहे हैं और भाषा के विचारों के अनुकूल नहीं हैं। आप जो दोष देखते हैं, वे दूसरों को एक फीचर पर विचार करते हैं। –

+0

मैंने केवल [इस बात] की वजह से उस टिप्पणी को जोड़ा (http://meta.stackoverflow.com/questions/315419/should-perl6-questions-be-tagged-with-the-perl-tag-as-well) और क्योंकि मैं वास्तव में यह सुनिश्चित नहीं था कि यह व्यवहार जानबूझकर था, एक बग या अगर मैं खराब हो रहा था। – cat

5

[जब से तुम दोनों एक Perl5 और एक Perl6 जवाब के लिए कहा, लेकिन आप केवल एक Perl6 जवाब, यहाँ एक Perl5 जवाब है। मिला]

आप एक सेशन चेकर कि जो कि जाँच के साथ अनुक्रमण ऑप्स की जगह लिख सकता है सीमाएं (उसी तरह no autovivification; उन संस्करणों के साथ dereferencing ops को प्रतिस्थापित करता है जो स्वत: प्रदान नहीं करते हैं।)

+0

'पता नहीं कैसे' कोई ऑटोविविफिकेशन नहीं ' 'अभी तक' – cat

+0

यह सही जवाब जैसा प्रतीत होता है, अगर राकुडो को पता था कि 'कोई ऑटोवॉर्पोरेट' कैसे नहीं है – cat

+2

मुझे पता नहीं था कि राकुडो पर्ल 5 चला सकता है। – ikegami

9

यह वही करेगा जो आप चाहते हैं।

my @a is default(Failure.new('IndexError')); 
@a[0] = 1; 
say @a[1]; 
say 'alive'; 

output: 

===SORRY!=== 
IndexError 

आप एक स्टैकट्रेस आप या तो perl6 --ll-exception चलाने के लिए या Proxy साथ अपने स्वयं के कंटेनर बनाने के लिए चाहते हैं। (यह एक बग है, के रूप में रिपोर्ट: RT#127414)

see: https://doc.perl6.org/type/Failure 
see: https://doc.perl6.org/routine/is%20default 
see: https://perl6advent.wordpress.com/2015/12/02/day-2-2-bind-or-2-bind/ 

ओह, और कृपया वालों में जो पर्ल 6. पर्ल 6 के पूरे मुद्दे के लिए अनुकूल करने के लिए आपको बताना चाहता हूँ को सुनने नहीं है आप कर सकते हैं वह यह है कि इसे सुधारो और अपनी इच्छानुसार मोड़ो।

class NonvivArray is Array { 
    multi method AT-POS(NonvivArray:D: Int:D $pos) is raw { 
     say 'foo'; 
     my $val = callsame; 
     X::OutOfRange.new(got=>$pos, range=>0..self.elems-1).throw unless $val; 
     $val; 
    } 

    multi method AT-POS(NonvivArray:D: int $ipos) is raw { 
     say 'foo'; 
     my $val = callsame; 
     X::OutOfRange.new(got=>$ipos, range=>0..self.elems-1).throw unless $val; 
     $val; 
    } 
} 

my NonvivArray $a; 
$a.push: 1; 
dd $a; 
say $a[1]; 

ऐसा करने के दो और तरीके हैं। यहां तीसरा है।

try { 
    my Int:D @a; 
    say @a[0]; 
    CATCH { default { say .^name } } 
} 
# OUTPUT«X::Method::NotFound␤» 

कोई तर्क दे सकता है कि अपवाद फेंक दिया गया एलटीए है या यह वास्तव में विशेषीकृत होना चाहिए। हालांकि, यह वही करता है जो ओपी ने राकूदो द्वारा लागू Array के कार्यान्वयन विवरण के बिना झुकाए बिना पूछा।

+1

कूल! यह वही है जो मैं ढूंढ रहा था! अब, उदाहरण के लिए, मैं 'लिस्ट' से प्राप्त एक प्रकार को परिभाषित कर सकता हूं और जो 'विफलता' नया ("इंडेक्स एरर") पर डिफ़ॉल्ट है, इसलिए मुझे बस 'मेरा सुरक्षितसूची @ ए' लिखना है? – cat

+3

मैंने ऐरे के लिए एक उप-वर्ग जोड़ा। मैं यह जानने का दावा नहीं करता कि मैं क्या कर रहा हूं। जैसे ही आप अनंत सूचियों और/या वादों का उपयोग करते हैं, वे आपके चेहरे में सबसे अधिक संभावनाएं उड़ाएंगे (जो अनंत सूची हैं जब तक वे नहीं हैं)। कि आप अपनी इच्छा के लिए पर्ल 6 मोड़ सकते हैं इसका मतलब यह नहीं है कि यह आपको काट नहीं देगा। –

+3

मैंने पढ़ा है और इस प्रकार अप्रत्याशित सॉफ़्टवेयर उपयोगकर्ता लाइसेंस अनुबंध – cat

2

आप Acme::Array::MaxSize से प्रेरित हो सकते हैं - यानी आप सरणी संचालन को रोकने के लिए Tie::Array का उपयोग कर सकते हैं।

संबंधित मुद्दे