2010-09-10 6 views
5

मैं सरल स्केला लिपियों कि अंत की तरह args पर एक साधारण पैटर्न मैच के साथ शुरू के एक नंबर लिखने में त्रुटि संदेश देना तर्कों की गलत संख्या, मुझे एक अचूक त्रुटि मिलती है जैसे:पैटर्न मैच args और एक हल्के स्काला स्क्रिप्ट

scala.MatchError: [Ljava.lang.String;@7786df0f 
    at Main$$anon$1.<init>(FollowUsers.scala:5) 
    ... 

क्या कोई और उपयोगी त्रुटि संदेश देने का कोई आसान तरीका है? मेरे वर्तमान वैकल्पिक हल की तरह कुछ करने के लिए है:

args match { 
    case Array(path, foo, whatever) => someFunction(path, foo, whatever) 
    case _ => System.err.println("usage: path foo whatever") 
} 
def someFunction(path: String, foo: String, whatever: String) = { 
    // .. rest of the script uses "path", "foo", etc. 
} 

लेकिन उस बॉयलरप्लेट का एक बहुत की तरह लगता है क्या एक पूरी अन्य समारोह को परिभाषित करने के लिए, और "पथ", "foo" और "जो कुछ भी" को दोहराने के लिए होने के साथ इतने सारे स्थान क्या कोई बेहतर तरीका है? मुझे लगता है कि मैं समारोह खो सकता हूं और शरीर को मैच स्टेटमेंट में डाल सकता हूं, लेकिन यह मेरे लिए कम पठनीय लगता है।

मुझे पता है कि मैं कई कमांड लाइन तर्क पार्सिंग पैकेजों में से एक का उपयोग कर सकता हूं, लेकिन मैं वास्तव में बहुत हल्का वजन ढूंढ रहा हूं कि मुझे निर्भरता जोड़ने और मेरे क्लासपाथ को संशोधित करने की आवश्यकता नहीं है।

try { 
    val Array(path, foo, whatever) = args 
} catch { 
    case _: MatchError => System.err.println("usage: path foo whatever") 
} 

उत्तर

3

कैसे?

val Array(path, foo, whatever) = if (args.length == 3) args 
    else throw new Exception("usage:path foo whatever") 

== संपादित ==

रंडाल्स टिप्पणी के आधार पर:

require(args.length == 3, "usage: path foo whatever") 
val Array(path, foo, whatever) = args 

न्यूनतम बॉयलरप्लेट है यही कारण है कि। आपके vals गुंजाइश में हैं, आपको बंद ब्रेस से निपटने की ज़रूरत नहीं है और आपको उपयोग त्रुटि संदेश मिलता है।

+0

हाँ, मुझे लगता है कि यह ठीक है, हालांकि आपको एक सीधा त्रुटि संदेश के बजाय एक स्टैक ट्रेस मिलेगा। – Steve

+0

यही 'आवश्यकता' के लिए है। जैसे 'की आवश्यकता है (args.length == 3," तर्कों में XYZ को कॉल में लम्बाई तीन होना चाहिए ") ' –

+0

" आवश्यकता "वाला संस्करण अच्छा और सरल है। हालांकि आपको इसके साथ एक सुंदर वर्बोज अपवाद मिलता है: 'java.lang।IllegalArgumentException: आवश्यकता विफल: उपयोग: पथ foo जो कुछ भी (और फिर सभी सामान्य ट्रेसबैक)। स्कैला डेवलपर को सही समझ में आता है, लेकिन किसी ऐसे व्यक्ति के लिए थोड़ा भ्रमित हो सकता है जो स्कैला को नहीं जानता लेकिन सिर्फ मेरी स्क्रिप्ट का उपयोग करना चाहता है। – Steve

1

एक तरह से MatchError को पकड़ने के लिए है पहले संभालना और शेष कोड को एक साथ रखता है, हालांकि यह मुझे इतना बड़ा प्रयास करने के लिए थोड़ा परेशान करता है (कि ऐरे पैटर्न मिलान के साथ दूसरा ब्लॉक अनिवार्य रूप से सभी एक ही प्रयास ब्लॉक में है अपवाद द्वारा झुकाव।

संपादित करें: ऐसा लगता है कि गायब फ़ैक्टर ने भी वही चीज़ पोस्ट की है, लेकिन स्पष्ट रूप से परिभाषित फ़ंक्शन और लागू करने के लिए एक स्पष्ट कॉल के साथ।

+0

लेकिन फिर "पथ", "foo" और "जो कुछ भी" प्रयास/पकड़ के बाद दायरे से बाहर हो जाएगा। तो आपको मूल रूप से उपरोक्त कोड के समान ही करना होगा - या तो एक सहायक फ़ंक्शन जोड़ें, या कोशिश ब्लॉक में संपूर्ण मुख्य विधि को परिभाषित करें। – Steve

3
scala> val args = Array("evil", "mad", "scientist") 
args: Array[java.lang.String] = Array(evil, mad, scientist) 

scala> def logToConsole(th: Throwable) { Console.err.println("Usage: path foo bar") } 
logToConsole: (th: Throwable)Unit 

scala> handling(classOf[MatchError]) by logToConsole apply { 
    | val Array(path, foo, bar) = args 
    | println(path) 
    | } 
evil 

scala> handling(classOf[MatchError]) by logToConsole apply { 
    | val Array(path, foo, bar) = Array("#fail") 
    | println(path) 
    | } 
Usage: path foo bar 
+1

हाँ, मैं बस एक ही चीज़ के साथ आया था। इस दृष्टिकोण का नकारात्मक पक्ष यह है कि यदि स्क्रिप्ट में कुछ भी एक मैचरर फेंकता है, तो हैंडलर इसे कमांड लाइन तर्कों की तरह दिखता है, जो वास्तविक मिलान त्रुटि को छुपाता है। – Steve

0

मुझे लगा कि शायद नए util.control.Exception एक समाधान हो सकता है:

import scala.util.control.Exception 

Exception.handling(classOf[scala.MatchError]).by{ 
    e => System.err.println("usage: path foo whatever") 
} { 
    val Array(path, foo, whatever) = args 
    // .. rest of the script uses "path", "foo", etc. 
} 

यह कम से कम त्रुटि डालता