2012-06-10 6 views
9
में

तो मैं Erlang सीखने शुरू कर दिया है और मैं एक छोटे से कोड के इस खंड के साथ भ्रमित कर रहा हूँ।चयनात्मक प्राप्त Erlang

-module(prior). 
-compile(export_all). 


    important() -> 
     receive 
    { Priority, Msg } when Priority > 10 -> 
     [Msg | important()] 
    after 0 -> 
    normal() 
    end. 

normal() -> 
    receive 
    { _, Msg } -> 
     [Msg | normal()] 
    after 0 -> 
     [] 
    end. 

मैं कोड का उपयोग कर कॉल कर रहा हूं।

10> self() ! {15, high}, self() ! {7, low}, self() ! {1, low}, self() ! {17, high}. 
    {17,high} 
    11> prior:important(). 
     [high,high,low,low] 

मैं समझता हूं कि यह कोड पहले सभी प्राथमिकता संदेशों और फिर कम प्राथमिकता वाले लोगों के माध्यम से जाएगा। मैं उलझन में हूं कि वापसी मूल्य [उच्च, उच्च, निम्न, निम्न] कैसे है, क्योंकि मुझे नहीं लगता कि वे कहां एकत्रित हैं।

+1

concatenated नहीं, consed। concatenation तब होता है जब आपके पास दो सूचियां होती हैं, 'L1' और 'L2' और उन्हें संयोजित करें:' L1 ++ L2'। खपत तब होती है जब आपके पास तत्व 'ई' और एक सूची' एल' होती है और फिर विस्तारित सूची '[ई | एल] '। –

उत्तर

14

कैसे अंतिम वापसी मान का निर्माण किया है ...

[Msg | important()] पहली बार के लिए वापस आ जा रहा है, अंतिम वापसी मान के रूप निर्धारित होता है। एकमात्र चिंता यह है कि हम अभी तक अंतिम वापसी मूल्य के सभी विवरण नहीं जानते हैं। तो [Msg | important()] में important() का मूल्यांकन जारी रहेगा। निम्नलिखित का एक उदाहरण है कि अंतिम वापसी मूल्य [high,high,low,low] का निर्माण कैसे किया जाता है।

[high | important(     )] <---- Defines the final form 
     --------------------------------- 
     [high | important(   )] <---- Adds more details 
       ------------------------ 
       normal(    ) <---- Adds more details 
       ------------------------ 
       [low | normal(  )] <---- Adds more details 
         ---------------- 
         [low | normal()]  <---- Adds more details 
           -------- 
           [  ]  <---- Adds more details 
------------------------------------------ 
[high | [high | [low | [low | []]]]] 
[high,high,low,low]       <---- The final return value 

कैसे कोड काम करता है ...

समारोह important/0 में, after 0 सीधा सा अर्थ है "संदेश आने के लिए मैं इंतजार नहीं है" - होगा कि मेरे मेलबॉक्स में किसी भी संदेश है, मैं इसे देखेंगे; यदि कोई नहीं है, तो मैं वहां रहने के बजाय (normal() निष्पादित) जारी रखूंगा।मेलबॉक्स में, {15, उच्च}, {7, निम्न}, {1, निम्न}, {17, उच्च} पहले से ही वहां बैठे हैं। एरलांग में, मेलबॉक्स में संदेश पहले आओ-प्रथम-सेवा क्रम में कतारबद्ध नहीं हैं। receive खंड picky हो सकता है। यह मेलबॉक्स में सभी संदेशों के माध्यम से स्कैन करता है और जो चाहती है उसे "चुनता है"। हमारे मामले में, {15, उच्च} और {17, उच्च}{Priority, Msg} when Priority > 10 के अनुसार पहले उठाया गया। उसके बाद, फ़ंक्शन normal/0 लेता है। और {7, कम}, {1, कम} क्रमशः संसाधित (consed) प्राप्त करें। अंत में, हमें [high,high,low,low] मिला।

एक संशोधित संस्करण है कि प्रसंस्करण आदेश का पता चलता है ...

हम आदेश प्रसंस्करण (consing) क्रम अधिक स्पष्ट बनाने के लिए कोड एक छोटा सा संशोधित कर सकते हैं:

-module(prior). 
-compile(export_all). 

important() -> 
    receive 
    {Priority, Msg} when Priority > 10 -> 
     [{Priority, Msg} | important()] % <---- Edited 
    after 0 -> 
    normal() 
    end. 

normal() -> 
    receive 
    {Priority, Msg} -> % <---- Edited 
     [{Priority, Msg} | normal()] % <---- Edited 
    after 0 -> 
     [] 
    end. 

भागो खोल में यह:

4> c(prior). 
{ok, prior} 
5> self() ! {15, high}, self() ! {7, low}, self() ! {1, low}, self() ! {17, high}. 
{17,high} 
6> prior:important(). 
[{15,high},{17,high},{7,low},{1,low}] 
+2

मैंने ओपी को कोड लिखा था (मुझे विश्वास है कि यह मेरी प्राथमिकता है कुछ सीखने में आपको कुछ Erlang) और मैं इस जवाब को स्वीकार करता हूं। –

4

वे यहाँ

[Msg | important()] 

इस important() concated कर रहे हैं एक समारोह है, तो यह एक वापसी मान होता है, जबकि आप इस आरईपीएल में चला वह समारोह से वापसी मान प्रिंट होगा। यह मान से import()

important() यहाँ [Head | Tail] सूची निर्माण के प्रभाव एक नियमित रूप से समारोह :)

यह उपयोगी है है?

+0

त्वरित उत्तर के लिए धन्यवाद। तो बाद में सामान्य() कॉल से प्राप्त कम प्राथमिकता संदेश को उच्च प्राथमिकता सूची में शामिल किया गया है [संदेश | महत्वपूर्ण()] खंड? – tkblackbelt

+0

सबकुछ। यदि आपके पास लोड के संदेश भी हों तो शायद यह आपके रैम को बाढ़ देगा ताकि आपको इसे पूंछ रिकर्सिव फ़ंक्शन में घुमाया जाए। मुझे नहीं पता कि आप क्या बनाने की कोशिश कर रहे हैं क्योंकि सामान्य रूप से यह सामान्य डेटा संरचना के रूप में प्राथमिकता वाले क्यू के साथ gen_server होना चाहिए। आप इसे एक प्रक्रिया संदेश क्यू के अंदर करने की कोशिश कर रहे हैं और यह बात सीमित है इसलिए सामान्य रूप से यह बुरा विचार है। –

2

सभी Erlang कार्यों हमेशा कोई मान। फ़ंक्शन important/0 को उच्च प्राथमिकता संदेश प्राप्त होगा और फिर [Msg | important()] अभिव्यक्ति में स्वयं को कॉल करें जो नवीनतम Msg युक्त एक सूची बनाता है और अन्य सभी संदेश जो important/0 प्राप्त करेंगे। यह सूची है जो important/0 से वापस आती है। कोई और अधिक उच्च प्राथमिकता संदेशों देखते हैं तो important/0 बजाय normal/0 फोन सभी शेष संदेश पढ़ने के लिए होगा। संदेशों जो normal/0 इसे पढ़ता है उसी तरह important/0 में एक सूची के रूप वापस आ जाएगी। इसे important/0 पर वापस कर दिया जाएगा जो इसे उसी सूची में वापस कर देगा क्योंकि उसने अपने संदेश वापस कर दिए हैं।

ध्यान दें कि एक बार normal/0 कहा गया है कि उच्च प्राथमिकता संदेशों का कोई विशेष संचालन नहीं होगा क्योंकि important/0 को कभी भी कभी नहीं कहा जाता है। important/0 वास्तव में केवल कतार में उच्च प्राथमिकता वाले संदेशों को संसाधित करेगा क्योंकि एक बार यह और नहीं मिल सकता है तो यह normal/0 पर कॉल करता है।

टाइमआउट मान 0 विशेष है कि इसमें तुरंत समय लगता है लेकिन संदेशों से मेल खाने के लिए पूरी संदेश कतार की खोज करने की गारंटी देता है।