2009-03-20 9 views
13

तो जब कोई उपयोगकर्ता खाता पंजीकृत करने का अनुरोध भेजता है, तो वे अपना उपयोगकर्ता नाम, पासवर्ड, ईमेल और अन्य जानकारी भेजते हैं। पंजीकरण फ़ंक्शन को उनके सभी डेटा को सत्यापित करना होगा। एक उदाहरण होगा:मैं Erlang में कई स्थितियों की खूबसूरती से जांच कैसे करूं?

  • उपयोग
  • में नहीं ईमेल को सत्यापित उपयोग
  • को सत्यापित उपयोगकर्ता नाम में नहीं उपयोगकर्ता नाम की पुष्टि अक्षरांकीय
  • की पुष्टि सभी क्षेत्रों में लंबे समय के
  • की पुष्टि सभी क्षेत्रों कम कर रहे हैं एक्स वर्ण से ऊपर हैं है वाई वर्णों की तुलना में

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

मैं उन्हें फ़ंक्शंस में अलग कर सकता हूं और फिर सभी कंडीशनरों के साथ एक कथन कथन कर सकता हूं, लेकिन यह मुझे वह नहीं देगा जो मुझे चाहिए क्योंकि मुझे उपयोगकर्ता को विशिष्ट त्रुटि बताने में सक्षम होना चाहिए एक था

कोई इस तरह की स्थिति को एर्लांग में कैसे संभालता है? क्या रिटर्न स्टेटमेंट के बराबर है, या क्या यह रिटर्न वैल्यू होने के लिए फ़ंक्शन में अंतिम निष्पादन योग्य रेखा होनी चाहिए?

+0

एरलांग मेलिंग सूची के साथ एक क्रॉस पोस्ट - अब क्रॉस-पोस्ट की उचित संख्या हो रही है ... –

उत्तर

32

जो आर्मस्ट्रांग के सुझाव में से एक: प्रोग्राम सफलता केस कोड त्रुटि प्रबंधन से अलग है। आप इस तरह से

create_user(Email, UserName, Password) -> 
    try 
    ok = new_email(Email), 
    ok = valid_user_name(UserName), 
    ok = new_user(UserName), 
    ok = strong_password(Password), 
    ... 
    _create_user(Email, UserName, Password) 
    catch 
    error:{badmatch, email_in_use} -> do_something(); 
    error:{badmatch, invalid_user_name} -> do_something(); 
    error:{badmatch, user_exists} -> do_something(); 
    error:{badmatch, weak_password} -> do_something(); 
    ... 
    end. 

ध्यान दें कि आप सभी त्रुटियों कर सकते हैं create_user समारोह जो बेहतर है से बाहर फैल जाती है में यह कर सकते हैं।

create_user(Email, UserName, Password) -> 
    ok = new_email(Email), 
    ok = valid_user_name(UserName), 
    ok = new_user(UserName), 
    ok = strong_password(Password), 
    ... 
    _create_user(Email, UserName, Password). 

main() -> 
    try 
    ... 
    some_function_where_create_user_is_called(), 
    ... 
    catch 
    ... 
    error:{badmatch, email_in_use} -> do_something(); 
    error:{badmatch, invalid_user_name} -> do_something(); 
    error:{badmatch, user_exists} -> do_something(); 
    error:{badmatch, weak_password} -> do_something(); 
    ... 
    end. 

पैटर्न मिलान एरलांग में सबसे अच्छी चीजों में से एक है। ध्यान दें कि आप तो अपवाद काफी तेजी से है के लिए आप अपनी अपेक्षाओं की निर्भर करता है त्रुटि

{my_tag, ok} = {my_tag, my_call(X)} 

और कस्टम डेटा भी

{my_tag, ok, X} = {my_tag, my_call(X), X} 

badmatch के लिए अपने टैग को शामिल कर सकते हैं। मेरे 2.2 गीगाहर्ट्ज कोर 2 डुओ इंटेल पर गति: 6 लाख सफलता (बाहरी) फ़ंक्शन कॉल (0.146US) की तुलना में एक सेकंड (0.47us) में लगभग 2 मिलियन अपवाद - एक अनुमान लगा सकता है कि अपवाद हैंडलिंग लगभग 0.32us लेता है। देशी कोड में यह 6.8 बनाम 47 लाख प्रति सेकेंड है और हैंडलिंग में लगभग 0.125us लग सकते हैं। कोशिश-पकड़ निर्माण के लिए कुछ अतिरिक्त लागत हो सकती है जो देशी और बाइट-कोड दोनों में सफलता फ़ंक्शन कॉल के लिए लगभग 5-10% है।

+2

उत्तर के लिए +1: दोनों erlang पुस्तकों पर 'स्पष्ट नहीं है कि आप अधिक से अधिक डाल सकते हैं कोशिश/कैच पर एक अभिव्यक्ति। जानकारी के लिए Ty! – scooterman

+0

क्या इसे 'new_email' जैसे कार्यों को एक विशिष्ट प्रकार की त्रुटि फेंकने की आवश्यकता है जैसे 'email_in_use'? – Tommy

+0

@ टॉमी: नहीं, बस वापस लौटें: 'ठीक कोशिश करें = (मजेदार() -> email_in_use अंत)() त्रुटि पकड़ें: {badmatch, email_in_use} -> io: प्रारूप ("ठीक है! ~ N", []) अंत। ' –

4
User = get_user(), 

Check_email=fun(User) -> not is_valid_email(User#user.email) end, 
Check_username=fun(User) -> is_invalid_username(User#user.name) end, 

case lists:any(fun(Checking_function) -> Checking_function(User) end, 
[Check_email, Check_username, ... ]) of 
true -> % we have problem in some field 
    do_panic(); 
false -> % every check was fine 
    do_action() 
end 

तो यह अब 5 स्तर गहरा नहीं है। वास्तविक कार्यक्रम के लिए मुझे लगता है कि आपको सूचियों का उपयोग करना चाहिए: प्रत्येक जांच फ़ंक्शन से त्रुटि संदेश जमा करने के लिए फ़ोल्डर। क्योंकि अब के लिए यह सरल है 'ठीक है' या 'कुछ समस्या'।

ध्यान दें कि इस तरह से जोड़ सकते हैं या हालत जाँच को दूर एक बड़ी बात

और के लिए नहीं है "वहाँ एक वापसी कथन के समान है ..." - कोशिश पकड़ फेंक बयान को देखो, की तरह काम करती फेंक इस मामले में वापसी करें।

-3

शायद तुम,

receive 
    message1 -> code1; 
    message2 -> code2; 
    ... 
end. 

का उपयोग करते हुए की आवश्यकता होगी लेकिन निश्चित रूप से, वहाँ अंडे किया जाएगा() तरीकों।

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