Erlang 21 - 3. Using Unicode in Erlang

3 एरलांग में यूनिकोड का उपयोग करना




erlang

3 एरलांग में यूनिकोड का उपयोग करना

3.1 यूनिकोड कार्यान्वयन

यूनिकोड चरित्र सेट के लिए समर्थन को लागू करना एक सतत प्रक्रिया है। एरलंग एन्हांसमेंट प्रपोजल (ईईपी) 10 में यूनिकोड समर्थन की मूल बातें बताई गई हैं और बायनेरिज़ में एक डिफ़ॉल्ट एन्कोडिंग को निर्दिष्ट किया गया है जो सभी यूनिकोड-जागरूक मॉड्यूल को भविष्य में संभालना है।

यहाँ एक सिंहावलोकन है जो अब तक किया गया है:

  • EEP10 में वर्णित कार्यक्षमता को Erlang / OTP R13A में लागू किया गया था।

  • Erlang / OTP R14B01 ने यूनिकोड फ़ाइलनाम के लिए समर्थन जोड़ा, लेकिन यह पूर्ण नहीं था और प्लेटफ़ॉर्म पर डिफ़ॉल्ट रूप से अक्षम था जहाँ फ़ाइल नाम एन्कोडिंग के लिए कोई गारंटी नहीं दी गई थी।

  • Erlang / OTP के साथ R16A UTF-8 एन्कोडेड सोर्स कोड के लिए समर्थन के साथ आया, जिसमें यूनिकोड एन्कोडेड फाइलनेम और UTF-8 एन्कोडेड फ़ाइलों के लिए कई परिस्थितियों में दोनों का समर्थन करने के लिए कई अनुप्रयोगों में वृद्धि हुई। सबसे उल्लेखनीय फाइल द्वारा पढ़ी गई फाइलों में UTF-8 के लिए समर्थन है file:consult/1 , UTF-8 के लिए रिलीज़ हैंडलर समर्थन, और I / O सिस्टम में यूनिकोड वर्ण सेट के लिए अधिक समर्थन।

  • Erlang / OTP 17.0 में, Erlang स्रोत फ़ाइलों के लिए एन्कोडिंग डिफ़ॉल्ट UTF-8 पर स्विच किया गया था।

  • Erlang / OTP 20.0 में, परमाणु और फ़ंक्शन में यूनिकोड वर्ण हो सकते हैं। मॉड्यूल नाम, एप्लिकेशन नाम और नोड नाम अभी भी आईएसओ लैटिन -1 श्रेणी तक ही सीमित हैं।

    unicode में सामान्यीकरण रूपों के लिए समर्थन जोड़ा गया था और string मॉड्यूल अब utf8- एन्कोडेड बायनेरी को संभालता है।

यह खंड वर्तमान यूनिकोड समर्थन को रेखांकित करता है और यूनिकोड डेटा के साथ काम करने के लिए कुछ व्यंजन देता है।

3.2 यूनिकोड को समझना

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

इसके अलावा, Erlang कार्यान्वयन के लिए उन अवधारणाओं की समझ की आवश्यकता होती है जो कई (Erlang) प्रोग्रामर के लिए कभी कोई समस्या नहीं थीं। यूनिकोड वर्णों को समझने और उनका उपयोग करने के लिए आवश्यक है कि आप विषय का गहन अध्ययन करें, भले ही आप एक अनुभवी प्रोग्रामर हों।

एक उदाहरण के रूप में, ऊपरी और निचले मामले पत्रों के बीच परिवर्तित करने के मुद्दे पर विचार करें। मानक पढ़ने से आपको एहसास होता है कि सभी लिपियों में एक से एक मैपिंग के लिए एक सरल नहीं है, उदाहरण के लिए:

  • जर्मन में, "ß" (तेज एस) अक्षर कम मामले में है, लेकिन बड़े पैमाने पर समकक्ष "एसएस" है।

  • ग्रीक में, "Σ" शब्द के दो अलग-अलग लोअरकेस फॉर्म हैं, शब्द-अंतिम स्थिति में "in" और अन्य जगहों पर "el"।

  • तुर्की में, डॉटेड और डॉटलेस "i" दोनों निचले मामले और ऊपरी मामले रूपों में मौजूद हैं।

  • सिरिलिक "I" का आमतौर पर कोई लोअरकेस फॉर्म नहीं होता है।

  • ऊपरी मामले (या निचले मामले) की कोई अवधारणा वाली भाषाएं।

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

एक और उदाहरण उच्चारण पात्र हैं, जहां एक ही ग्लिफ़ के दो अलग-अलग अभ्यावेदन हैं। स्वीडिश पत्र "ö" एक उदाहरण है। यूनिकोड मानक के पास इसके लिए एक कोड बिंदु है, लेकिन आप इसे "ओ" के रूप में "यू + 0308" के साथ भी लिख सकते हैं (संयोजन का संयोजन, सरलीकृत अर्थ के साथ कि अंतिम पत्र "ऊपर" है)। उनके पास एक ही ग्लिफ़ है, उपयोगकर्ता माना चरित्र। वे अधिकांश उद्देश्यों के लिए समान हैं, लेकिन अलग-अलग अभ्यावेदन हैं। उदाहरण के लिए, MacOS X सभी फ़ाइलनामों को कंबाइनिंग डाइरेसिस का उपयोग करने के लिए कनवर्ट करता है, जबकि अधिकांश अन्य प्रोग्राम (Erlang सहित) को छिपाने की कोशिश करते हैं, उदाहरण के लिए, लिस्टिंग निर्देशिका। हालांकि यह किया जाता है, भ्रम से बचने के लिए ऐसे पात्रों को सामान्य करना महत्वपूर्ण है।

उदाहरणों की सूची लंबी की जा सकती है। एक प्रकार के ज्ञान की आवश्यकता होती है जब कार्यक्रमों को केवल एक या दो भाषाओं में माना जाता है। सार्वभौमिक मानक बनाते समय मानव भाषाओं और लिपियों की जटिलता ने निश्चित रूप से इसे एक चुनौती बना दिया है। आपके कार्यक्रम में यूनिकोड का ठीक से समर्थन करने के लिए प्रयास की आवश्यकता होगी।

3.3 यूनिकोड क्या है

यूनिकोड सभी ज्ञात, जीवित या मृत, लिपियों के लिए एक मानक परिभाषित कोड अंक (संख्या) है। सिद्धांत रूप में, किसी भी भाषा में उपयोग किए जाने वाले प्रत्येक प्रतीक में एक यूनिकोड कोड बिंदु होता है। यूनिकोड कोड पॉइंट्स को यूनिकोड कंसोर्टियम द्वारा परिभाषित और प्रकाशित किया जाता है, जो एक गैर-लाभकारी संगठन है।

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

एनकोडिंग और यूनिकोड वर्णों के बीच के अंतर को समझना महत्वपूर्ण है। यूनिकोड वर्ण यूनिकोड मानक के अनुसार कोड पॉइंट हैं, जबकि एनकोडिंग ऐसे कोड पॉइंट का प्रतिनिधित्व करने के तरीके हैं। एक एन्कोडिंग केवल प्रतिनिधित्व के लिए एक मानक है। उदाहरण के लिए, यूटीएफ -8 का उपयोग यूनिकोड चरित्र सेट (उदाहरण के लिए आईएसओ-लैटिन -1) या पूर्ण यूनिकोड श्रेणी के बहुत सीमित हिस्से का प्रतिनिधित्व करने के लिए किया जा सकता है। यह केवल एक एन्कोडिंग प्रारूप है।

जब तक सभी वर्ण सेट 256 वर्णों तक सीमित थे, तब तक प्रत्येक वर्ण को एक एकल बाइट में संग्रहीत किया जा सकता था, इसलिए वर्णों के लिए केवल एक या अधिक व्यावहारिक एन्कोडिंग थी। प्रत्येक चरित्र को एक बाइट में एन्कोड करना इतना सामान्य था कि एन्कोडिंग का नाम भी नहीं था। यूनिकोड प्रणाली के साथ 256 से अधिक वर्ण हैं, इसलिए इनका प्रतिनिधित्व करने के लिए एक सामान्य तरीके की आवश्यकता है। कोड बिंदुओं का प्रतिनिधित्व करने के सामान्य तरीके एनकोडिंग हैं। इसका मतलब है प्रोग्रामर के लिए एक पूरी नई अवधारणा, चरित्र प्रतिनिधित्व की अवधारणा, जो पहले एक गैर-मुद्दा था।

विभिन्न ऑपरेटिंग सिस्टम और टूल अलग-अलग एनकोडिंग का समर्थन करते हैं। उदाहरण के लिए, लिनक्स और मैकओएस एक्स ने यूटीएफ -8 एन्कोडिंग को चुना है, जो 7-बिट एएससीआईआई के साथ संगत है और इसलिए सादे अंग्रेजी में लिखे गए कार्यक्रमों को कम से कम प्रभावित करता है। विंडोज़ UTF-16 के सीमित संस्करण का समर्थन करता है, अर्थात् सभी कोड प्लेन जहाँ वर्णों को एक एकल 16-बिट इकाई में संग्रहीत किया जा सकता है, जिसमें अधिकांश जीवित भाषाएँ शामिल हैं।

निम्नलिखित सबसे व्यापक रूप से फैले हुए एनकोडिंग हैं:

बाइटवाइज़ प्रतिनिधित्व

यह एक उचित यूनिकोड प्रतिनिधित्व नहीं है, लेकिन यूनिकोड मानक से पहले पात्रों के लिए इस्तेमाल किया गया प्रतिनिधित्व है। इसका उपयोग अभी भी संख्याओं के साथ यूनिकोड मानक में वर्ण कोड बिंदुओं का प्रतिनिधित्व करने के लिए किया जा सकता है <256, जो वास्तव में आईएसओ लैटिन -1 वर्ण सेट से मेल खाती है। एरलैंग में, यह आमतौर पर लैटिन 1 एन्कोडिंग निरूपित किया जाता है, जो आईएसओ लैटिन -1 के रूप में थोड़ा भ्रामक है, एक कोड कोड है, एन्कोडिंग नहीं।

UTF-8

प्रत्येक वर्ण कोड बिंदु के आधार पर एक से चार बाइट्स में संग्रहीत किया जाता है। एन्कोडिंग 7-बिट ASCII के बाइटीव्यू प्रतिनिधित्व के साथ पिछड़ा संगत है, क्योंकि सभी 7-बिट वर्ण UTF-8 में एक एकल बाइट में संग्रहीत हैं। कोड बिंदु 127 से परे के पात्रों को अधिक बाइट्स में संग्रहीत किया जाता है, जिससे पहले चरित्र में सबसे महत्वपूर्ण बिट एक मल्टी-बाइट चरित्र को इंगित करता है। एन्कोडिंग पर विवरण के लिए, RFC सार्वजनिक रूप से उपलब्ध है।

ध्यान दें कि यूटीएफ -8, 255 के माध्यम से 128 से कोड बिंदुओं के लिए अटूट प्रतिनिधित्व के साथ संगत नहीं है , इसलिए आईएसओ लैटिन -1 उप-प्रतिनिधित्व प्रतिनिधित्व आमतौर पर यूटीएफ -8 के साथ असंगत है।

UTF-16

इस एन्कोडिंग में UTF-8 की कई समानताएँ हैं, लेकिन मूल इकाई 16-बिट संख्या है। इसका मतलब है कि सभी वर्ण कम से कम दो बाइट्स पर कब्जा करते हैं, और कुछ उच्च संख्या में चार बाइट्स। कुछ प्रोग्राम, लाइब्रेरी और ऑपरेटिंग सिस्टम, जो यूटीएफ -16 का उपयोग करने का दावा करते हैं, केवल उन पात्रों के लिए अनुमति देते हैं जिन्हें एक 16-बिट इकाई में संग्रहीत किया जा सकता है, जो आमतौर पर जीवित भाषाओं को संभालने के लिए पर्याप्त है। चूंकि मूल इकाई एक से अधिक बाइट होती है, बाइट-ऑर्डर की समस्याएं होती हैं, यही वजह है कि यूटीएफ -16 एक बड़े-एंडियन और थोड़ा-एंडियन संस्करण में मौजूद है।

एरलैंग में, पूर्ण यूटीएफ -16 रेंज को लागू किया जाता है, जैसे unicode मॉड्यूल और बिट सिंटैक्स में।

UTF-32

सबसे सीधा प्रतिनिधित्व। प्रत्येक वर्ण को एक एकल 32-बिट संख्या में संग्रहीत किया जाता है। एक चरित्र के लिए पलायन या किसी भी परिवर्तनशील संख्या की कोई आवश्यकता नहीं है। सभी यूनिकोड कोड बिंदु एक एकल 32-बिट इकाई में संग्रहीत किए जा सकते हैं। यूटीएफ -16 के साथ, बाइट-ऑर्डर मुद्दे हैं। UTF-32 बड़े एंडियन और छोटे एंडियन दोनों हो सकते हैं।

यूसीएस -4

मूल रूप से UTF-32 के समान है, लेकिन IEEE द्वारा परिभाषित कुछ यूनिकोड शब्दार्थ के बिना, और अलग एन्कोडिंग मानक के रूप में इसका बहुत कम उपयोग होता है। सभी सामान्य (और संभवतः असामान्य) उपयोग के लिए, UTF-32 और UCS-4 विनिमेय हैं।

यूनिकोड मानक में कुछ निश्चित रेंज का उपयोग नहीं किया जाता है और कुछ रेंज को अमान्य भी माना जाता है। सबसे उल्लेखनीय अमान्य सीमा 16 # D800-16 # DFFF है, क्योंकि UTF-16 एन्कोडिंग इन नंबरों की एन्कोडिंग की अनुमति नहीं देता है। यह संभवतः इसलिए है क्योंकि शुरू से ही यूटीएफ -16 एन्कोडिंग मानक, एक 16-बिट इकाई में सभी यूनिकोड वर्णों को धारण करने में सक्षम होने की उम्मीद थी, लेकिन फिर इसे आगे बढ़ाया गया, जिससे बैकवर्ड संगतता को संभालने के लिए यूनिकोड रेंज में एक छेद छोड़ दिया गया।

कोड बिंदु 16 # FEFF का उपयोग बाइट ऑर्डर मार्क्स (BOMs) के लिए किया जाता है और अन्य संदर्भों में उस चरित्र के उपयोग को प्रोत्साहित नहीं किया जाता है। हालांकि यह वैध है, क्योंकि चरित्र "ZWNBS" (शून्य चौड़ाई गैर ब्रेकिंग स्पेस)। बीओएम का उपयोग उन कार्यक्रमों के लिए एन्कोडिंग और बाइट ऑर्डर की पहचान करने के लिए किया जाता है जहां ऐसे पैरामीटर पहले से ज्ञात नहीं हैं। बीओएम उम्मीद से अधिक शायद ही कभी उपयोग किए जाते हैं, लेकिन वे अधिक व्यापक रूप से फैल सकते हैं क्योंकि वे कार्यक्रमों के लिए एक निश्चित फ़ाइल के यूनिकोड प्रारूप के बारे में शिक्षित अनुमान लगाने के लिए साधन प्रदान करते हैं।

3.4 यूनिकोड समर्थन के क्षेत्र

Erlang में यूनिकोड का समर्थन करने के लिए, विभिन्न क्षेत्रों में समस्याओं का समाधान किया गया है। यह अनुभाग इस उपयोगकर्ता की मार्गदर्शिका में प्रत्येक क्षेत्र का संक्षिप्त और बाद में पूरी तरह से वर्णन करता है।

प्रतिनिधित्व

Erlang में यूनिकोड वर्णों को संभालने के लिए, सूचियों और बायनेरिज़ दोनों में एक सामान्य प्रतिनिधित्व की आवश्यकता है। EEP (10) और Erlang / OTP R13A में बाद के प्रारंभिक कार्यान्वयन ने Ericang में यूनिकोड वर्णों का एक मानक प्रतिनिधित्व बसाया।

जोड़-तोड़

यूनिकोड के पात्रों को एरलांग कार्यक्रम द्वारा संसाधित करने की आवश्यकता है, यही कारण है कि पुस्तकालय कार्यों को उन्हें संभालने में सक्षम होना चाहिए। कुछ मामलों में कार्यक्षमता पहले से ही मौजूदा इंटरफेस में जोड़ दी गई है (क्योंकि string मॉड्यूल अब किसी भी कोड बिंदुओं के साथ तारों को संभाल सकता है)। कुछ मामलों में नई कार्यक्षमता या विकल्प जोड़े गए हैं (जैसे कि io मॉड्यूल, फ़ाइल हैंडलिंग, unicode मॉड्यूल और बिट सिंटैक्स)। आज कर्नेल और एसटीडीआईएलबी में अधिकांश मॉड्यूल, साथ ही साथ वीएम यूनिकोड-जागरूक हैं।

फ़ाइल I / O

मैं / O अब तक यूनिकोड के लिए सबसे अधिक समस्याग्रस्त क्षेत्र है। एक फ़ाइल एक इकाई है जहां बाइट्स संग्रहीत किए जाते हैं, और प्रोग्रामिंग की विद्या को अक्षर और बाइट्स को विनिमेय माना जाता है। यूनिकोड वर्णों के साथ, आपको एक एन्कोडिंग पर निर्णय लेना चाहिए जब आप किसी फ़ाइल में डेटा संग्रहीत करना चाहते हैं। एर्लैंग में, आप एक एन्कोडिंग विकल्प के साथ एक पाठ फ़ाइल खोल सकते हैं, ताकि आप बाइट्स के बजाय उससे वर्ण पढ़ सकें, लेकिन आप एक फाइल को I / O के लिए भी खोल सकते हैं।

Erlang I / O-system को इस तरह से डिजाइन किया गया है (या कम से कम उपयोग किया जाता है) जहां आप किसी भी I / O सर्वर से किसी भी स्ट्रिंग डेटा को संभालने की अपेक्षा करते हैं। हालांकि, यूनिकोड वर्णों के साथ काम करते समय अब ​​ऐसा नहीं है। Erlang प्रोग्रामर को अब उस डिवाइस की क्षमताओं को जानना चाहिए जहां डेटा समाप्त होता है। इसके अलावा, एरलांग में बंदरगाह बाइट-ओरिएंटेड हैं, इसलिए एक मनमाना स्ट्रिंग ऑफ (यूनिकोड) वर्ण पहली पसंद के एन्कोडिंग में परिवर्तित किए बिना पोर्ट पर नहीं भेजा जा सकता है।

टर्मिनल I / O

टर्मिनल I / O फ़ाइल I / O की तुलना में थोड़ा आसान है। आउटपुट मानव पढ़ने के लिए है और आमतौर पर एर्लांग सिंटैक्स (उदाहरण के लिए, शेल में) है। ग्लिफ़ को प्रदर्शित किए बिना किसी भी यूनिकोड वर्ण का सिंटैक्टिक प्रतिनिधित्व मौजूद है (इसके बजाय \x { HHH } लिखा जाता है)। यूनिकोड डेटा को आमतौर पर प्रदर्शित किया जा सकता है भले ही टर्मिनल इस तरह से पूरे यूनिकोड रेंज का समर्थन नहीं करता हो।

फ़ाइल नाम

फ़ाइलनाम को अंतर्निहित ऑपरेटिंग सिस्टम और फ़ाइल सिस्टम के आधार पर अलग-अलग तरीकों से यूनिकोड स्ट्रिंग के रूप में संग्रहीत किया जा सकता है। यह एक प्रोग्राम द्वारा काफी आसान तरीके से हैंडल किया जा सकता है। समस्या तब आती है जब फ़ाइल सिस्टम अपने एन्कोडिंग्स में असंगत है। उदाहरण के लिए, लिनक्स उन बाइट्स की व्याख्या करने के लिए प्रत्येक प्रोग्राम को छोड़कर बाइट्स के किसी भी अनुक्रम के साथ फ़ाइलों को नामित करने की अनुमति देता है। सिस्टम पर जहां इन "पारदर्शी" फ़ाइलनामों का उपयोग किया जाता है, एर्लैंग को स्टार्टअप फ्लैग द्वारा फ़ाइल नाम एन्कोडिंग के बारे में सूचित किया जाना चाहिए। डिफ़ॉल्ट बाइविट व्याख्या है, जो आमतौर पर गलत है, लेकिन सभी फ़ाइलनामों की व्याख्या के लिए अनुमति देता है।

"कच्चे फ़ाइलनाम" की अवधारणा का उपयोग गलत तरीके से एन्कोड किए गए फ़ाइलनामों को संभालने के लिए किया जा सकता है यदि कोई उन प्लेटफार्मों पर यूनिकोड फ़ाइलनाम अनुवाद ( +fnu ) को सक्षम करता है जहां यह डिफ़ॉल्ट नहीं है।

स्रोत कोड एन्कोडिंग

Erlang स्रोत कोड में UTF-8 एन्कोडिंग और बायटिव एन्कोडिंग के लिए समर्थन है। Erlang / OTP R16B में डिफ़ॉल्ट बायटिव (लैटिन 1) एन्कोडिंग था। इसे बदलकर UTF-8 में Erlang / OTP 17.0 कर दिया गया। आप फ़ाइल की शुरुआत में निम्नलिखित की तरह एक टिप्पणी द्वारा एन्कोडिंग को नियंत्रित कर सकते हैं:

%% -*- coding: utf-8 -*-

इस कोर्स के लिए आपके संपादक को UTF-8 का समर्थन करने की आवश्यकता है। एक ही टिप्पणी को file:consult/1 जैसे कार्यों द्वारा भी व्याख्या की जाती है file:consult/1 , रिलीज हैंडलर, और इसी तरह, ताकि आप अपने स्रोत निर्देशिकाओं में सभी पाठ फ़ाइलों को UTF-8 एन्कोडिंग में रख सकें।

भाषा

UTF-8 में स्रोत कोड होने से आप स्ट्रिंग अंकल, फ़ंक्शन नाम और कोड पॉइंट> 255 के साथ यूनिकोड वर्णों वाले परमाणुओं को भी लिख सकते हैं। मॉड्यूल नाम, एप्लिकेशन नाम और नोड नाम अभी भी आईएसओ लैटिन -1 रेंज तक सीमित हैं। द्विआधारी शाब्दिक, जहां आप टाइप /utf8 का उपयोग करते हैं, को यूनिकोड वर्णों> 255 का उपयोग करके भी व्यक्त किया जा सकता है। 7-बिट एएससीआईआई के अलावा अन्य वर्णों का उपयोग करके मॉड्यूल नाम या एप्लिकेशन नाम होने से असंगत फ़ाइल नामकरण योजनाओं के साथ ऑपरेटिंग सिस्टम पर परेशानी हो सकती है और पोर्टेबिलिटी को नुकसान पहुंचा सकता है। , तो यह अनुशंसित नहीं है।

ईईपी 40 बताता है कि भाषा को यूनिकोड वर्णों के लिए भी अनुमति है> 255 चर नामों में। क्या यह लागू करना है कि ईईपी अभी तय नहीं किया गया है।

3.5 मानक यूनिकोड प्रतिनिधित्व

एरलंग में, तार पूर्णांक की सूची है। एक स्ट्रिंग तब तक थी जब तक Erlang / OTP R13 को आईएसओ लैटिन -1 (ISO 8859-1) वर्ण सेट में कूटबद्ध किया जाना था, जो कि कोड बिंदु, कोड बिंदु, यूनिकोड वर्ण सेट की एक व्यवस्था है।

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

आईएसओ लातिन -1 में एरलंग के तार यूनिकोड के तार के सबसेट हैं।

केवल अगर एक स्ट्रिंग में कोड अंक <256 हैं, तो इसका उपयोग करके सीधे बाइनरी में परिवर्तित किया जा सकता है, उदाहरण के लिए, erlang:iolist_to_binary/1 या सीधे पोर्ट में भेजा जा सकता है। यदि स्ट्रिंग में यूनिकोड वर्ण> 255 हैं, तो एक एन्कोडिंग का निर्णय लिया जाना चाहिए और स्ट्रिंग को unicode:characters_to_binary/1,2,3 का उपयोग करके पसंदीदा एन्कोडिंग में एक बाइनरी में unicode:characters_to_binary/1,2,3 । स्ट्रिंग्स आम तौर पर बाइट्स की सूची नहीं हैं, क्योंकि वे एर्लांग / ओटीपी आर 13 से पहले थे, वे पात्रों की सूची हैं। वर्ण आमतौर पर बाइट्स नहीं होते हैं, वे यूनिकोड कोड पॉइंट होते हैं।

बायनेरिज़ अधिक परेशान हैं। प्रदर्शन कारणों से, कार्यक्रम अक्सर सूचियों के बजाय बायनेरिज़ में पाठ डेटा संग्रहीत करते हैं, मुख्यतः क्योंकि वे अधिक कॉम्पैक्ट होते हैं (प्रति वर्ण दो शब्दों के बजाय प्रति वर्ण, जैसा कि सूचियों के मामले में है)। erlang:list_to_binary/1 का उपयोग करना erlang:list_to_binary/1 , एक आईएसओ लैटिन -1 Erlang स्ट्रिंग को बाइनरी में परिवर्तित किया जा सकता है, प्रभावी रूप से बाइट एन्कोडिंग का उपयोग करते हुए: एक बाइट प्रति वर्ण। यह उन सीमित एरलंग स्ट्रिंग्स के लिए सुविधाजनक था, लेकिन यूनिकोड सूचियों के लिए नहीं किया जा सकता है।

चूंकि UTF-8 एन्कोडिंग व्यापक रूप से फैली हुई है और 7-बिट ASCII रेंज में कुछ पिछड़ी संगतता प्रदान करती है, इसलिए इसे एरलैंग के लिए बायनेरिज़ में यूनिकोड वर्णों के लिए मानक एन्कोडिंग के रूप में चुना गया है।

मानक द्विआधारी एन्कोडिंग का उपयोग तब किया जाता है जब बायलर में यूनिकोड डेटा को संभालने के लिए एरलांग में एक लाइब्रेरी फ़ंक्शन होता है, लेकिन बाहरी रूप से संचार करते समय इसे लागू नहीं किया जाता है। कार्य और बिट सिंटैक्स दोनों बायनेरिज़ में UTF-8, UTF-16 और UTF-32 को एन्कोड और डिकोड करने के लिए मौजूद हैं। हालाँकि, सामान्य रूप से केवल बायनेरिज़ और यूनिकोड के साथ काम करने वाले लाइब्रेरी फ़ंक्शंस डिफ़ॉल्ट इनकोडिंग से निपटते हैं।

चरित्र डेटा को कई स्रोतों से जोड़ा जा सकता है, कभी-कभी तार और बायनेरिज़ के मिश्रण में उपलब्ध होता है। iolist लंबे समय से iolist या iolist की अवधारणा है, जहां बाइट्स और सूचियों को बाइट्स के अनुक्रम का प्रतिनिधित्व करने के लिए जोड़ा जा सकता है। उसी तरह, यूनिकोड-जागरूक मॉड्यूल अक्सर बायनेरिज़ और सूचियों के संयोजन की अनुमति देते हैं, जहां बायनेरिज़ के पास यूटीएफ -8 में एन्कोड किए गए अक्षर होते हैं और सूचियों में ऐसे बायनेरिज़ या नंबर होते हैं जो यूनिकोड कोड बिंदुओं का प्रतिनिधित्व करते हैं:

unicode_binary() = binary() with characters encoded in UTF-8 coding standard

chardata() = charlist() | unicode_binary()

charlist() = maybe_improper_list(char() | unicode_binary() | charlist(),
  unicode_binary() | nil())

मॉड्यूल unicode भी unicode -8 की तुलना में अन्य एनकोडिंग वाले बायनेरिज़ के साथ समान मिश्रण का समर्थन करता है, लेकिन बाहरी डेटा से और रूपांतरण के लिए अनुमति देने के लिए यह एक विशेष मामला है:

external_unicode_binary() = binary() with characters coded in a user-specified
  Unicode encoding other than UTF-8 (UTF-16 or UTF-32)

external_chardata() = external_charlist() | external_unicode_binary()

external_charlist() = maybe_improper_list(char() | external_unicode_binary() |
  external_charlist(), external_unicode_binary() | nil())

3.6 मूल भाषा समर्थन

Erlang / OTP R16 से, Erlang स्रोत फ़ाइलों को UTF-8 या bytewise ( latin1 ) एन्कोडिंग में लिखा जा सकता है। इरलांग स्रोत फ़ाइल के एन्कोडिंग को कैसे epp(3) , इस बारे में जानकारी के लिए, epp(3) मॉड्यूल देखें। एर्लैंग / ओटीपी आर 16 से, यूनिकोड का उपयोग करके तार और टिप्पणियां लिखी जा सकती हैं। एर्लैंग / ओटीपी 20 से, यूनिकोड का उपयोग करके भी परमाणु और फ़ंक्शन लिखे जा सकते हैं। मॉड्यूल, अनुप्रयोग और नोड्स को अभी भी आईएसओ लैटिन -1 वर्ण सेट से वर्णों का उपयोग करके नाम दिया जाना चाहिए। (भाषा में ये प्रतिबंध स्रोत फ़ाइल के एन्कोडिंग से स्वतंत्र हैं।)

बिट सिंटेक्स

बिट सिंटैक्स में तीन मुख्य एन्कोडिंग में बाइनरी डेटा को संभालने के लिए प्रकार होते हैं। प्रकारों का नाम utf8 , utf16 और utf32 utf16 और utf32 प्रकार एक बड़े-एंडियन या एक छोटे-एंडियन संस्करण में हो सकते हैं:

<<Ch/utf8,_/binary>> = Bin1,
<<Ch/utf16-little,_/binary>> = Bin2,
Bin3 = <<$H/utf32-little, $e/utf32-little, $l/utf32-little, $l/utf32-little,
$o/utf32-little>>,

सुविधा के लिए, निम्नलिखित (या समान) सिंटैक्स का उपयोग करके बायनेरिज़ में यूनिकोड एन्कोडिंग के साथ शाब्दिक तार को एन्कोड किया जा सकता है:

Bin4 = <<"Hello"/utf16>>,

स्ट्रिंग और चरित्र साहित्य

स्रोत कोड के लिए, सिंटैक्स \ OOO (तीन अष्टक संख्याओं के बाद बैकस्लैश) और \x एचएच ( x बाद बैकस्लैश, दो हेक्साडेसिमल वर्णों के बाद), अर्थात् \x{ एच } (बैकस्लैश } है। x , इसके बाद बाएं घुंघराले ब्रैकेट, हेक्साडेसिमल अंकों की कोई भी संख्या और एक सही कर्ली ब्रैकेट)। यह किसी भी कोड बिंदु के अक्षर को वस्तुतः स्ट्रिंग में तब भी दर्ज करने की अनुमति देता है, जब स्रोत फ़ाइल का एन्कोडिंग bytewise ( latin1 ) हो।

शेल में, यदि यूनिकोड इनपुट डिवाइस का उपयोग किया जाता है, या UTF-8 में संग्रहीत स्रोत कोड में, तो सीधे एक यूनीकोड ​​चरित्र द्वारा पूर्णांक का उत्पादन किया जा सकता है। निम्नलिखित उदाहरण में, सिरिलिक с का कोड बिंदु आउटपुट है:

7> $с.
1089

ह्यूरिस्टिक स्ट्रिंग डिटेक्शन

कुछ आउटपुट फ़ंक्शंस में और शेल में रिटर्न वैल्यूज़ के आउटपुट में, एरलैंग सूची और बायनेरिज़ में कड़े डेटा का पता लगाने की कोशिश करता है। आमतौर पर आप इस तरह की स्थिति में हेयुरिस्टिक डिटेक्शन देखेंगे:

1> [97,98,99].
"abc"
2> <<97,98,99>>.
<<"abc">>    
3> <<195,165,195,164,195,182>>.
<<"åäö"/utf8>>

यहाँ शैल सूची का पता लगाता है जिसमें मुद्रण योग्य वर्ण या बायनेरिज़ या मुद्रण योग्य वर्णों वाले बायनेरीज़ शामिल हैं जो UTF-8 एन्कोडिंग हैं। लेकिन एक मुद्रण योग्य चरित्र क्या है? एक दृश्य यह है कि यूनिकोड मानक के अनुसार कुछ भी मुद्रण योग्य है, यह भी अनुमान के अनुसार मुद्रण योग्य है। परिणाम तब होता है कि पूर्णांक की लगभग किसी भी सूची को एक स्ट्रिंग माना जाता है, और सभी प्रकार के वर्ण मुद्रित होते हैं, शायद यह भी वर्ण कि आपके टर्मिनल में इसके फ़ॉन्ट सेट की कमी है (जिसके परिणामस्वरूप कुछ अप्राप्य जेनेरिक आउटपुट हैं)। एक और तरीका यह है कि इसे पिछड़े संगत रखा जाए ताकि स्ट्रिंग का पता लगाने के लिए केवल आईएसओ लैटिन -1 चरित्र सेट का उपयोग किया जाए। एक तीसरा तरीका यह है कि उपयोगकर्ता ठीक-ठीक तय कर दे कि यूनिकोड की कौन-सी श्रेणियाँ हैं जिन्हें वर्णों के रूप में देखा जा सकता है।

Erlang / OTP R16B के रूप में, आप क्रमशः ISO फ़्लैग -1 श्रेणी या संपूर्ण यूनिकोड श्रेणी का चयन स्टार्टअप फ़्लैग +pc latin1 लैटिन 1 या +pc latin1 यूनिकोड की आपूर्ति करके कर सकते हैं। पिछड़े संगतता के लिए, latin1 डिफ़ॉल्ट है। यह केवल नियंत्रित करता है कि कैसे हेरास्टिक स्ट्रिंग का पता लगाया जाता है। भविष्य में और अधिक श्रेणियों को जोड़े जाने की उम्मीद है, जिससे उपयोगकर्ता के लिए प्रासंगिक भाषा और क्षेत्र की सिलाई को सक्षम किया जा सके।

निम्नलिखित उदाहरण दो स्टार्टअप विकल्प दिखाते हैं:

$ erl +pc latin1
Erlang R16B (erts-5.10.1) [source] [async-threads:0] [hipe] [kernel-poll:false]

Eshell V5.10.1  (abort with ^G)  
1> [1024].
[1024]
2> [1070,1085,1080,1082,1086,1076].
[1070,1085,1080,1082,1086,1076]
3> [229,228,246].
"åäö"
4> <<208,174,208,189,208,184,208,186,208,190,208,180>>.
<<208,174,208,189,208,184,208,186,208,190,208,180>>
5> <<229/utf8,228/utf8,246/utf8>>.
<<"åäö"/utf8>>
$ erl +pc unicode
Erlang R16B (erts-5.10.1) [source] [async-threads:0] [hipe] [kernel-poll:false]

Eshell V5.10.1  (abort with ^G)  
1> [1024].
"Ѐ"
2> [1070,1085,1080,1082,1086,1076].
"Юникод"
3> [229,228,246].
"åäö"
4> <<208,174,208,189,208,184,208,186,208,190,208,180>>.
<<"Юникод"/utf8>>
5> <<229/utf8,228/utf8,246/utf8>>.
<<"åäö"/utf8>>

उदाहरणों में, आप देख सकते हैं कि डिफ़ॉल्ट एर्लैंग शेल आईएसओ लैटिन 1 रेंज के केवल वर्णों को प्रिंट करने योग्य के रूप में व्याख्या करता है और केवल स्ट्रिंग डेटा वाले "प्रिंट करने योग्य" पात्रों के साथ सूचियों या बायनेरी का पता लगाता है। वैध यूटीएफ -8 बाइनरी जिसमें रूसी शब्द "дникод" है, एक स्ट्रिंग के रूप में मुद्रित नहीं है। जब सभी यूनिकोड अक्षरों को प्रिंट करने योग्य ( +pc unicode ) के साथ शुरू किया जाता है, तो शेल स्ट्रिंग डेटा के रूप में मुद्रण योग्य यूनिकोड डेटा (बायनेरिज़, या तो यूटीएफ -8 या बायटेज एनकोडेड) वाले कुछ भी आउटपुट करता है।

इन अनुमानों का उपयोग io:format/2 , io_lib:format/2 , और मित्रों द्वारा किया जाता है जब संशोधक t का उपयोग ~p या ~P : के साथ किया जाता है

$ erl +pc latin1
Erlang R16B (erts-5.10.1) [source] [async-threads:0] [hipe] [kernel-poll:false]

Eshell V5.10.1  (abort with ^G)  
1> io:format("~tp~n",[{<<"åäö">>, <<"åäö"/utf8>>, <<208,174,208,189,208,184,208,186,208,190,208,180>>}]).
{<<"åäö">>,<<"åäö"/utf8>>,<<208,174,208,189,208,184,208,186,208,190,208,180>>}
ok
$ erl +pc unicode
Erlang R16B (erts-5.10.1) [source] [async-threads:0] [hipe] [kernel-poll:false]

Eshell V5.10.1  (abort with ^G)  
1> io:format("~tp~n",[{<<"åäö">>, <<"åäö"/utf8>>, <<208,174,208,189,208,184,208,186,208,190,208,180>>}]).
{<<"åäö">>,<<"åäö"/utf8>>,<<"Юникод"/utf8>>}
ok

ध्यान दें कि यह केवल उत्पादन पर सूचियों और बायनेरिज़ की अनुमानी व्याख्या को प्रभावित करता है। उदाहरण के लिए, ~ts प्रारूप अनुक्रम हमेशा वर्णों की एक मान्य सूची को आउटपुट करता है, भले ही +pc सेटिंग की परवाह किए बिना, क्योंकि प्रोग्रामर ने स्पष्ट रूप से स्ट्रिंग आउटपुट का अनुरोध किया है।

3.7 इंटरएक्टिव शेल

इंटरैक्टिव Erlang खोल, जब एक टर्मिनल पर शुरू हुआ या विंडोज पर कमांड werl का उपयोग करना शुरू कर दिया, तो यूनिकोड इनपुट और आउटपुट का समर्थन कर सकता है।

विंडोज पर, उचित संचालन के लिए आवश्यक है कि एर्लैंग एप्लिकेशन का उपयोग करने के लिए एक उपयुक्त फ़ॉन्ट स्थापित और चयनित हो। यदि आपके सिस्टम पर कोई उपयुक्त फ़ॉन्ट उपलब्ध नहीं है, तो DejaVu fonts स्थापित करने का प्रयास करें, जो स्वतंत्र रूप से उपलब्ध हैं, और फिर Erlang शेल एप्लिकेशन में उस फ़ॉन्ट का चयन करें।

यूनिक्स-जैसे ऑपरेटिंग सिस्टम पर, टर्मिनल को इनपुट और आउटपुट पर UTF-8 को संभालने में सक्षम होना है (यह उदाहरण के लिए, XTerm, KDE Konsole और Gnome टर्मिनल के आधुनिक संस्करण) और आपके लोकेल को होना चाहिए उचित। एक उदाहरण के रूप में, एक LANG पर्यावरण चर निम्नानुसार सेट किया जा सकता है:

$ echo $LANG
en_US.UTF-8

अधिकांश सिस्टम LANG से पहले चर LC_CTYPE संभालते हैं, इसलिए यदि वह सेट है, तो इसे UTF-8 सेट किया जाना चाहिए:

$ echo $LC_CTYPE
en_US.UTF-8

LANG या LC_CTYPE सेटिंग टर्मिनल के अनुरूप होने के अनुरूप होनी चाहिए। Erlang के लिए अपनी UTF-8 क्षमता के बारे में टर्मिनल से पूछने का कोई पोर्टेबल तरीका नहीं है, हमें भाषा और चरित्र प्रकार सेटिंग्स पर भरोसा करना होगा।

Erlang टर्मिनल के बारे में क्या सोचता है, इसकी जांच करने के लिए, कॉल io:getopts() का उपयोग शेल शुरू होने पर किया जा सकता है:

$ LC_CTYPE=en_US.ISO-8859-1 erl
Erlang R16B (erts-5.10.1) [source] [async-threads:0] [hipe] [kernel-poll:false]

Eshell V5.10.1  (abort with ^G)
1> lists:keyfind(encoding, 1, io:getopts()).
{encoding,latin1}
2> q().
ok
$ LC_CTYPE=en_US.UTF-8 erl
Erlang R16B (erts-5.10.1) [source] [async-threads:0] [hipe] [kernel-poll:false]

Eshell V5.10.1  (abort with ^G)
1> lists:keyfind(encoding, 1, io:getopts()).
{encoding,unicode}
2>

जब (अंत में?) सब कुछ स्थानीय सेटिंग्स, फोंट के साथ होता है। और टर्मिनल एमुलेटर, आपको संभवतः आपकी इच्छा के अनुसार स्क्रिप्ट में इनपुट वर्णों का एक तरीका मिल गया है। परीक्षण के लिए, सबसे सरल तरीका अन्य भाषाओं के लिए कुछ कीबोर्ड मैपिंग जोड़ना है, जो आमतौर पर आपके डेस्कटॉप वातावरण में कुछ एप्लेट के साथ किया जाता है।

KDE वातावरण में, KDE नियंत्रण केंद्र (व्यक्तिगत सेटिंग्स) > क्षेत्रीय और पहुँच > कीबोर्ड लेआउट का चयन करें

Windows XP पर, नियंत्रण कक्ष > क्षेत्रीय और भाषा विकल्प , टैब भाषा का चयन करें, और पाठ सेवाओं और इनपुट भाषाओं नामक वर्ग में बटन विवरण ... का चयन करें।

आपका वातावरण संभवतः कीबोर्ड लेआउट को बदलने के समान साधन प्रदान करता है। सुनिश्चित करें कि आपके पास कीबोर्ड के बीच आगे और पीछे स्विच करने का एक तरीका है यदि आप इसके लिए उपयोग नहीं किए जाते हैं। उदाहरण के लिए, एरिलंग खोल में एक सिरिलिक वर्ण सेट का उपयोग करके कमांड दर्ज करना आसानी से नहीं होता है।

अब आप कुछ यूनिकोड इनपुट और आउटपुट के लिए सेट हैं। सबसे सरल कार्य शेल में एक स्ट्रिंग दर्ज करना है:

$ erl
Erlang R16B (erts-5.10.1) [source] [async-threads:0] [hipe] [kernel-poll:false]

Eshell V5.10.1  (abort with ^G)
1> lists:keyfind(encoding, 1, io:getopts()).
{encoding,unicode}
2> "Юникод".
"Юникод"
3> io:format("~ts~n", [v(2)]).
Юникод
ok
4>

हालांकि तार यूनिकोड वर्णों के रूप में इनपुट हो सकते हैं, भाषा तत्व अभी भी आईएसओ लैटिन -1 वर्ण सेट तक सीमित हैं। केवल चरित्र स्थिरांक और तार को उस सीमा से परे रहने की अनुमति है:

$ erl
Erlang R16B (erts-5.10.1) [source] [async-threads:0] [hipe] [kernel-poll:false]

Eshell V5.10.1  (abort with ^G)
1> $ξ.
958
2> Юникод.
* 1: illegal character
2> 

3.8 यूनिकोड फाइलनाम

अधिकांश आधुनिक ऑपरेटिंग सिस्टम किसी तरह से यूनिकोड फ़ाइलनाम का समर्थन करते हैं। यह करने के लिए कई अलग-अलग तरीके हैं और डिफ़ॉल्ट रूप से एरलंग अलग-अलग तरीकों से अलग-अलग व्यवहार करता है:

अनिवार्य यूनिकोड फ़ाइल का नामकरण

विंडोज और, अधिकांश सामान्य उपयोगों के लिए, मैकओएस एक्स फाइलनाम के लिए यूनिकोड समर्थन को लागू करता है। फाइल सिस्टम में बनाई गई सभी फाइलों में ऐसे नाम होते हैं जिनकी लगातार व्याख्या की जा सकती है। MacOS X में, सभी फ़ाइलनाम UTF-8 एन्कोडिंग में पुनर्प्राप्त किए जाते हैं। विंडोज में, प्रत्येक सिस्टम कॉल हैंडलिंग फ़ाइलनाम का एक विशेष यूनिकोड-जागरूक संस्करण होता है, जो एक ही प्रभाव देता है। इन प्रणालियों पर कोई फ़ाइल नाम नहीं हैं जो यूनिकोड फ़ाइल नाम नहीं हैं। तो, एरलंग वीएम का डिफ़ॉल्ट व्यवहार "यूनिकोड फाइलनेम ट्रांसलेशन मोड" में काम करना है। इसका मतलब है कि एक फ़ाइल नाम को यूनिकोड सूची के रूप में निर्दिष्ट किया जा सकता है, जो अंतर्निहित ऑपरेटिंग सिस्टम और फ़ाइल सिस्टम के लिए उचित नाम एन्कोडिंग के लिए स्वचालित रूप से अनुवादित है।

उदाहरण के लिए, file:list_dir/1 एक सिस्टम पर file:list_dir/1 , कोड सिस्टम> 255 के साथ यूनिकोड सूचियों को फाइल सिस्टम की सामग्री के आधार पर वापस कर सकता है।

पारदर्शी फ़ाइल नामकरण

अधिकांश यूनिक्स ऑपरेटिंग सिस्टम ने एक सरल दृष्टिकोण अपनाया है, जिसका अर्थ है कि यूनिकोड फ़ाइल का नामकरण लागू नहीं है, लेकिन सम्मेलन द्वारा। वे सिस्टम आमतौर पर यूनिकोड फाइलनाम के लिए UTF-8 एन्कोडिंग का उपयोग करते हैं, लेकिन इसे लागू नहीं करते हैं। इस तरह की प्रणाली पर, 255 के माध्यम से 128 से कोड बिंदुओं वाले वर्ण नाम को सादे आईएसओ लैटिन -1 के रूप में नामित किया जा सकता है या यूटीएफ -8 एन्कोडिंग का उपयोग किया जा सकता है। जैसा कि कोई निरंतरता लागू नहीं होती है, एर्लैंग वीएम सभी फ़ाइलनामों का लगातार अनुवाद नहीं कर सकता है।

ऐसे सिस्टम पर डिफ़ॉल्ट रूप से, Erlang utf8 फ़ाइल नाम मोड में शुरू होता है यदि टर्मिनल UTF-8 का समर्थन करता है, अन्यथा latin1 मोड में।

लैटिन 1 मोड में, फ़ाइल नाम को कूटबद्ध किया जाता है। यह सिस्टम में सभी फ़ाइलनामों की सूची प्रतिनिधित्व के लिए अनुमति देता है। हालाँकि, " file:list_dir/1 " नाम की एक फ़ाइल, फ़ाइल में दिखाई देती है file:list_dir/1 या तो "" file:list_dir/1 " के रूप में (यदि फ़ाइल फ़ाइल बनाने वाले प्रोग्राम द्वारा आईएसओ लैटिन लैटिन -1 में फ़ाइल नाम एनकोड किया गया था) या अधिक के रूप में संभवतः [195,150,115,116,101,114,115,117,110,100] , जो एक सूची है जिसमें UTF-8 बाइट्स (आप जो चाहते हैं) नहीं है। यदि आप ऐसी प्रणाली पर यूनिकोड फ़ाइल नाम का उपयोग करते हैं, तो गैर-यूटीएफ -8 फ़ाइलनामों को file:list_dir/1 जैसे फ़ंक्शन द्वारा अनदेखा किया जाता है। उन्हें फ़ंक्शन file:list_dir_all/1 साथ पुनर्प्राप्त किया जा सकता है file:list_dir_all/1 , लेकिन गलत तरीके से एन्कोड किए गए फ़ाइलनाम "कच्चे फ़ाइलनाम" के रूप में दिखाई देते हैं।

Erlang / OTP R14B01 में यूनिकोड फ़ाइल नामकरण समर्थन पेश किया गया था। यूनिकोड फ़ाइल नाम ट्रांसलेशन मोड में एक वीएम ऑपरेटिंग किसी भी भाषा या कैरेक्टर सेट (जब तक यह अंतर्निहित ऑपरेटिंग सिस्टम और फाइल सिस्टम द्वारा समर्थित है) में नाम वाली फाइलों के साथ काम कर सकता है। यूनीकोड ​​चरित्र सूची का उपयोग फ़ाइल नाम या निर्देशिका नामों को दर्शाने के लिए किया जाता है। यदि फ़ाइल सिस्टम सामग्री सूचीबद्ध है, तो आपको वापसी मूल्य के रूप में यूनिकोड सूची भी मिलती है। समर्थन कर्नेल और एसटीडीआईएलआईबी मॉड्यूल में निहित है, यही वजह है कि अधिकांश एप्लिकेशन (जिसमें स्पष्ट रूप से आईएसओ लातिन -1 रेंज में फाइलनेम की आवश्यकता नहीं है) बिना बदलाव के यूनिकोड समर्थन से लाभान्वित होते हैं।

अनिवार्य यूनिकोड फ़ाइलनाम के साथ ऑपरेटिंग सिस्टम पर, इसका मतलब है कि आप आसानी से अन्य (गैर-एरलंग) अनुप्रयोगों के फ़ाइलनाम के अनुरूप हैं। आप उन फ़ाइलनामों को भी संसाधित कर सकते हैं जो कम से कम विंडोज पर, दुर्गम थे (ऐसे नाम होने के कारण जिन्हें आईएसओ लैटिन -1 में प्रतिनिधित्व नहीं किया जा सकता था)। इसके अलावा, आप MacOS X पर vfs फ़ाइल नाम बनाने से बचते हैं, क्योंकि ऑपरेटिंग सिस्टम की vfs परत आपके सभी फ़ाइलनामों को स्वीकार कर vfs क्योंकि UTF-8 उन्हें फिर से नहीं लिखता है।

अधिकांश प्रणालियों के लिए, यूनिकोड फ़ाइल नाम का अनुवाद चालू करना कोई समस्या नहीं है, भले ही वह पारदर्शी फ़ाइल नामकरण का उपयोग करता हो। बहुत कम सिस्टम में फाइलनाम एनकोडिंग मिश्रित होती है। एक संगत UTF-8 नाम प्रणाली यूनिकोड फ़ाइलनाम मोड में पूरी तरह से काम करती है। हालांकि, यह अभी भी एर्लांग / OTP R14B01 में प्रयोगात्मक माना जाता था और अभी भी इस तरह के सिस्टम पर डिफ़ॉल्ट नहीं है।

यूनीकोड ​​फाइलनाम अनुवाद को स्विच +fnu साथ चालू किया गया है। लिनक्स पर, एक वीएम ने मूल फ़ाइल नाम एन्कोडिंग के रूप में लैटिन 1 में फ़ाइल नाम अनुवाद मोड डिफॉल्ट को स्पष्ट रूप से बताए बिना शुरू किया। Windows और MacOS X पर, डिफ़ॉल्ट व्यवहार यूनिकोड फ़ाइल नाम अनुवाद का है। इसलिए file:native_name_encoding/0 उन सिस्टमों पर डिफ़ॉल्ट रिटर्न utf8 द्वारा file:native_name_encoding/0 (फ़ाइल सिस्टम स्तर पर Windows UTF-8 का उपयोग नहीं करता है, लेकिन यह Erlang प्रोग्रामर द्वारा सुरक्षित रूप से अनदेखा किया जा सकता है)। डिफ़ॉल्ट व्यवहार, जैसा कि पहले कहा गया है, VM के विकल्प +fnu या +fnl का उपयोग करके बदला जा सकता है, erl प्रोग्राम देखें। यदि VM को यूनिकोड फ़ाइल नाम अनुवाद मोड में शुरू किया गया है, तो file:native_name_encoding/0 atom utf8 । स्विच +fnu को w , i , या e द्वारा नियंत्रित किया जा सकता है कि कैसे गलत तरीके से एन्कोड किए गए फ़ाइलनामों को सूचित किया जाए।

  • w अर्थ है कि जब भी कोई गलत तरीके से एन्कोडेड फ़ाइल नाम निर्देशिका सूचियों में "स्किप" किया जाता है, तो error_logger को एक चेतावनी भेजी जाती है। w डिफ़ॉल्ट है।

  • i मतलब है कि गलत तरीके से एन्कोड किए गए फ़ाइलनाम को चुपचाप अनदेखा कर दिया जाता है।

  • e मतलब है कि एपीआई फ़ंक्शन एक त्रुटि देता है जब भी गलत तरीके से एन्कोडेड फ़ाइल नाम (या निर्देशिका नाम) का सामना करना पड़ता है।

उस file:read_link/1 हमेशा एक त्रुटि देता है यदि लिंक किसी अमान्य फ़ाइलनाम की ओर file:read_link/1

यूनिकोड फ़ाइलनाम मोड में, बीआईएफ open_port/2 को विकल्प के साथ दिए गए फ़ाइलनाम की {spawn_executable,...} व्याख्या यूनिकोड के रूप में भी की जाती है। तो args उपयोग करते समय उपलब्ध विकल्प में निर्दिष्ट पैरामीटर सूची है spawn_executable । बिनारों के उपयोग से तर्कों का UTF-8 अनुवाद टाला जा सकता है, अनुभाग देखें Notes About Raw Filenames

ध्यान दें कि फ़ाइल खोलते समय निर्दिष्ट फ़ाइल एन्कोडिंग विकल्पों का फ़ाइल नाम एन्कोडिंग सम्मेलन से कोई लेना-देना नहीं है। आप UTF-8 में एन्कोडेड डेटा वाली फ़ाइलों को बहुत अच्छी तरह से खोल सकते हैं, लेकिन bytewise ( latin1 ) एन्कोडिंग या इसके विपरीत में फ़ाइल नाम रखना ।

ध्यान दें

Erlang ड्राइवरों और NIF- साझा की गई वस्तुओं को अभी भी कोड अंक> 127 वाले नामों के साथ नहीं रखा जा सकता है। यह सीमा भविष्य के रिलीज में हटा दी जाएगी। हालांकि, एर्लांग मॉड्यूल कर सकते हैं, लेकिन यह निश्चित रूप से एक अच्छा विचार नहीं है और अभी भी प्रयोगात्मक माना जाता है।

कच्चे फ़ाइलनाम के बारे में नोट्स

ध्यान दें

ध्यान दें कि आवश्यक रूप से कच्चे फ़ाइलनाम को ओएस स्तर पर उसी तरह एन्कोड नहीं किया गया है।

ERTS 5.8.2 (Erlang / OTP R14B01) में यूनिकोड फाइलनेम सपोर्ट के साथ रॉ फाइलनेम पेश किए गए। सिस्टम में "कच्चे फ़ाइलनाम" पेश किए जाने का कारण एक ही सिस्टम पर अलग-अलग एन्कोडिंग्स में निर्दिष्ट फ़ाइलनामों का प्रतिनिधित्व करने में सक्षम होना था। यह वीएम को स्वचालित रूप से एक फ़ाइलनाम का अनुवाद करने के लिए व्यावहारिक लग सकता है जो यूटीएफ -8 में यूनिकोड वर्णों की सूची में नहीं है, लेकिन यह डुप्लिकेट फ़ाइल नाम और अन्य असंगत व्यवहार दोनों के लिए खुल जाएगा।

ISO लैटिन -1 में "björn" नामक एक निर्देशिका पर विचार करें, जबकि Erlang VM यूनिकोड फ़ाइलनाम मोड में चल रहा है (और इसलिए UTF-8 फ़ाइल नामकरण की अपेक्षा करता है)। ISO लेटिन -1 नाम मान्य UTF-8 नहीं है और किसी को यह सोचने के लिए लुभाया जा सकता है कि उदाहरण के लिए, स्वचालित रूपांतरण file:list_dir/1 एक अच्छा विचार है। लेकिन अगर बाद में हमने फ़ाइल खोलने की कोशिश की और यूनिकोड सूची के रूप में नाम रखा (जादुई रूप से आईएसओ लैटिन -1 फ़ाइल नाम से परिवर्तित किया गया) तो क्या होगा? VM फ़ाइल नाम को UTF-8 में रूपांतरित करता है, क्योंकि यह एन्कोडिंग अपेक्षित है। प्रभावी रूप से इसका मतलब है कि << "björn" / utf8 >> नामक फ़ाइल को खोलने का प्रयास करें। यह फ़ाइल मौजूद नहीं है, और यहां तक ​​कि अगर यह अस्तित्व में है तो यह वही फ़ाइल नहीं होगी जो सूचीबद्ध थी। हम "björn" नाम की दो फाइलें भी बना सकते हैं, एक का नाम UTF-8 एन्कोडिंग और एक नहीं है। अगर file:list_dir/1 स्वचालित रूप से ISO लैटिन -1 फ़ाइल नाम को एक सूची में बदल देगा, हमें परिणाम के रूप में दो समान फ़ाइलनाम मिलेंगे। इससे बचने के लिए, हमें उन फ़ाइलनामों के बीच अंतर करना चाहिए जो कि यूनिकोड फ़ाइल नामकरण सम्मेलन (यानी, UTF-8) के अनुसार ठीक से एन्कोड किए गए हैं और फ़ाइलनाम जो एन्कोडिंग के तहत अमान्य हैं। सामान्य फ़ंक्शन द्वारा file:list_dir/1 , गलत तरीके से एन्कोड किए गए फ़ाइलनामों को यूनिकोड फ़ाइलनाम अनुवाद मोड में अनदेखा किया जाता है, लेकिन फ़ंक्शन द्वारा file:list_dir_all/1 अमान्य एन्कोडिंग वाले फ़ाइलनाम को "कच्चे" फ़ाइलनाम के रूप में लौटा दिया जाता है, अर्थात बायनेरिज़ के रूप में।

file मॉड्यूल इनपुट के रूप में कच्चे फ़ाइल नाम स्वीकार करता है। open_port({spawn_executable, ...} ...) उन्हें भी स्वीकार करता है। जैसा कि पहले उल्लेख किया गया है, विकल्प सूची में निर्दिष्ट तर्कों open_port({spawn_executable, ...} ...) को फाइलनाम के रूप में उसी रूपांतरण से गुजरना है, जिसका अर्थ है कि निष्पादन योग्य UTF-8 में तर्क के साथ भी प्रदान किया गया है। इस अनुवाद को लगातार इस बात से परहेज किया जाता है कि इस तर्क को एक द्विआधारी के रूप में देकर फाइलनाम के साथ कैसा व्यवहार किया जाता है।

उन सिस्टमों पर यूनिकोड फ़ाइल नाम अनुवाद को बाध्य करने के लिए जहां यह डिफ़ॉल्ट नहीं है, उन्हें Erlang / OTP R14B01 में प्रयोगात्मक माना गया था। ऐसा इसलिए था क्योंकि प्रारंभिक कार्यान्वयन ने गलत तरीके से एन्कोड किए गए फ़ाइलनामों को अनदेखा नहीं किया था, ताकि पूरे सिस्टम में कच्चे फ़ाइलनाम अप्रत्याशित रूप से फैल सकें। एर्लैंग / ओटीपी आर 16 बी के रूप में, गलत तरीके से एन्कोड किए गए फ़ाइल नाम केवल विशेष कार्यों (जैसे file:list_dir_all/1 ) द्वारा पुनर्प्राप्त किए जाते हैं । चूंकि मौजूदा कोड पर प्रभाव बहुत कम है इसलिए अब इसका समर्थन किया गया है। यूनिकोड फ़ाइल नाम का अनुवाद भविष्य के रिलीज में डिफ़ॉल्ट होने की उम्मीद है।

भले ही आप वीएम द्वारा स्वचालित रूप से यूनिकोड फ़ाइल नामकरण अनुवाद के बिना काम कर रहे हों, आप यूटीएफ -8 एन्कोडिंग के नाम से फाइल बना सकते हैं और यूटीएफ -8 के रूप में एन्कोड किए गए कच्चे फ़ाइलनाम का उपयोग करके एन्कोडिंग कर सकते हैं। मोड की परवाह किए बिना UTF-8 एन्कोडिंग को लागू करना, Erlang VM में शुरू किया गया है, कुछ परिस्थितियों में एक अच्छा विचार हो सकता है, क्योंकि UTF-8 फ़ाइलनाम का उपयोग करने का सम्मेलन फैल रहा है।

MacOS X के बारे में नोट्स

vfs MacOS X की परत एक आक्रामक तरीके से UTF-8 फाइलनाम को लागू करती है। पुराने संस्करणों ने गैर-यूटीएफ -8 के अनुरूप फ़ाइल नाम बनाने से इनकार करते हुए ऐसा किया, जबकि नए संस्करण ने बाइट्स को "% HH" अनुक्रम के साथ बदल दिया, जहां HH हेक्साडेसिमल नोटेशन में मूल चरित्र है। जैसा कि यूनिकोड अनुवाद मैकओएस एक्स पर डिफ़ॉल्ट रूप से सक्षम है, इसके खिलाफ आने का एकमात्र तरीका या तो झंडे के साथ वीएम शुरू करना है +fnl या बायटिव ( latin1 ) एन्कोडिंग में कच्चे फ़ाइलनाम का उपयोग करना है । यदि फ़ाइल बनाने के लिए 127 के माध्यम से 127 से वर्णों वाले बाइट एन्कोडिंग के साथ एक कच्चे फ़ाइलनाम का उपयोग किया जाता है, तो फ़ाइल को उसी नाम का उपयोग करके नहीं खोला जा सकता है जैसा कि इसे बनाने के लिए उपयोग किया जाता है। इस व्यवहार का कोई उपाय नहीं है, केवल फाइलिंग को सही एन्कोडिंग में रखने के अलावा।

MacOS X फाइलनामों को पुनर्गठित करता है ताकि उच्चारणों का प्रतिनिधित्व, और इसी तरह, "संयोजन वर्णों" का उपयोग किया जा सके। उदाहरण के लिए, चरित्र ö को कोड बिंदुओं के रूप में दर्शाया जाता है [111,776] , जहां 111 चरित्र है o और 776 विशेष उच्चारण चरित्र "कॉम्बिनेशन डायरिसिस" है। यूनिकोड को सामान्य करने का यह तरीका अन्यथा बहुत कम उपयोग किया जाता है। एर्लैंग उन फ़ाइलनामों को पुनः प्राप्ति पर सामान्य तरीके से सामान्य करता है, ताकि संयोजन लहजे का उपयोग करने वाले फ़ाइलनाम एर्लैंग एप्लिकेशन तक पारित न हों। एर्लैंग में, फ़ाइल नाम "björn" को पुनः प्राप्त किया जाता है [98,106,246,114,110] , जैसा कि नहीं [98,106,117,776,114,110] , हालांकि फ़ाइल सिस्टम अलग तरह से सोच सकता है। फ़ाइलों तक पहुँचने पर लहजे के संयोजन में सामान्यीकरण को फिर से तैयार किया जाता है, इसलिए इसे आमतौर पर एर्लांग प्रोग्रामर द्वारा अनदेखा किया जा सकता है।

3.9 पर्यावरण और पैरामीटर में यूनिकोड

पर्यावरण चर और उनकी व्याख्या को फ़ाइल नाम के समान ही नियंत्रित किया जाता है। यदि यूनिकोड फ़ाइलनाम सक्षम हैं, तो पर्यावरण चर और साथ ही एरलंग वीएम के पैरामीटर यूनिकोड में होने की उम्मीद है।

यूनिकोड फ़ाइल नामों सक्षम हैं, तो कॉल करने के लिए os:getenv/0,1 , os:putenv/2 और os:unsetenv/1 यूनिकोड तार संभाल। यूनिक्स-जैसे प्लेटफ़ॉर्म पर, अंतर्निहित फ़ंक्शन यूटीएफ -8 से / में यूनिकोड स्ट्रिंग्स से पर्यावरण चर का अनुवाद करते हैं, संभवतः कोड अंक> 255 के साथ। विंडोज पर, पर्यावरण प्रणाली एपीआई के यूनिकोड संस्करण उपयोग किए जाते हैं, और कोड अंक: 255 अनुमति हैं।

यूनिक्स जैसी ऑपरेटिंग सिस्टम पर, यदि यूनिकोड फ़ाइलनाम सक्षम हैं, तो मापदंडों को अनुवाद के बिना UTF-8 होने की उम्मीद है।

3.10 यूनिकोड-अवेयर मॉड्यूल

Erlang / OTP में अधिकांश मॉड्यूल इस मायने में यूनिकोड-अनजान हैं कि उनके पास यूनिकोड की कोई धारणा नहीं है और नहीं होनी चाहिए। आमतौर पर वे गैर-पाठीय या बाइट-ओरिएंटेड डेटा (जैसे gen_tcp ) को संभालते हैं ।

टेक्स्ट का डेटा (जैसे निपटने मॉड्यूल io_lib और string कभी कभी रूपांतरण या विस्तार के अधीन हैं यूनिकोड वर्ण को संभालने के लिए सक्षम होने के लिए।

सौभाग्य से, अधिकांश पाठ्य डेटा को सूचियों में संग्रहित किया गया है और सीमा जाँच विरल कर दी गई है, इसलिए string रूपांतरण या विस्तार के लिए बहुत कम आवश्यकता वाले यूनिकोड स्ट्रिंग्स के लिए मॉड्यूल काम करते हैं।

हालाँकि, कुछ मॉड्यूल यूनिकोड के प्रति स्पष्ट रूप से बदल दिए गए हैं। इन मॉड्यूल में शामिल हैं:

unicode

unicode मॉड्यूल स्पष्ट रूप से यूनिकोड-वाकिफ हैं। इसमें बाइट ऑर्डर के निशान की पहचान के लिए विभिन्न यूनिकोड स्वरूपों और कुछ उपयोगिताओं के बीच रूपांतरण के कार्य हैं। यूनिकोड डेटा को संभालने वाले कुछ प्रोग्राम इस मॉड्यूल के बिना जीवित रहते हैं।

io

io मॉड्यूल यूनिकोड डेटा को संभालने के लिए वास्तविक आई / ओ प्रोटोकॉल के साथ बढ़ा दिया गया है। इसका मतलब है कि कई कार्यों के लिए यूएनएफ -8 में बायनेरिज़ की आवश्यकता होती है, और यूनिकोड स्ट्रिंग्स के आउटपुट की अनुमति देने के लिए नियंत्रण अनुक्रमों को प्रारूपित करने के लिए संशोधक हैं।

file , group , user

पूरे सिस्टम में I / O- सर्वर यूनिकोड डेटा को संभाल सकते हैं और डिवाइस से आउटपुट / इनपुट पर / से डेटा को परिवर्तित करने के विकल्प हैं। जैसा कि पहले दिखाया गया है, shell मॉड्यूल में यूनिकोड टर्मिनलों के लिए समर्थन है और file मॉड्यूल डिस्क पर विभिन्न यूनिकोड प्रारूपों के अनुवाद के लिए अनुमति देता है।

यूनिकोड डेटा के साथ फ़ाइलों को पढ़ना और लिखना, हालांकि, file मॉड्यूल के साथ सबसे अच्छा नहीं है , क्योंकि इसका इंटरफ़ेस बाइट-ओरिएंटेड है। यूनिकोड एन्कोडिंग (जैसे UTF-8) के साथ खोली गई फ़ाइल io मॉड्यूल का उपयोग करके सबसे अच्छी तरह से पढ़ी या लिखी गई है ।

re

re मॉड्यूल एक विशेष विकल्प के रूप में यूनिकोड तार मिलान के लिए अनुमति देता है। चूंकि लाइब्रेरी बायनेरिज़ में मिलान पर केंद्रित है, यूनिकोड समर्थन UTF-8-केंद्रित है।

wx

चित्रमय पुस्तकालय wx में यूनिकोड पाठ के लिए व्यापक समर्थन है।

string मॉड्यूल यूनिकोड तार और आईएसओ लैटिन -1 स्ट्रिंग्स के लिए पूरी तरह से काम करता है, भाषा पर निर्भर कार्यों को छोड़कर string:uppercase/1 और string:lowercase/1 । ये दोनों फ़ंक्शन अपने वर्तमान रूप में यूनिकोड वर्णों के लिए सही ढंग से कार्य नहीं कर सकते हैं, क्योंकि मामलों के दौरान पाठ को परिवर्तित करते समय विचार करने के लिए भाषा और स्थानीय मुद्दे हैं। एक अंतरराष्ट्रीय वातावरण में परिवर्तित मामला एक बड़ा विषय है जिसे अभी तक ओटीपी में संबोधित नहीं किया गया है।

फाइलों में 3.11 यूनिकोड डेटा

हालांकि एर्लैंग कई रूपों में यूनिकोड डेटा को संभाल सकता है लेकिन इसका मतलब यह नहीं है कि किसी भी फ़ाइल की सामग्री यूनिकोड पाठ हो सकती है। बाहरी इकाइयाँ, जैसे पोर्ट और I / O सर्वर, आमतौर पर यूनिकोड सक्षम नहीं हैं।

पोर्ट हमेशा बाइट-ओरिएंटेड होते हैं, इसलिए डेटा भेजने से पहले कि आप सुनिश्चित नहीं हैं कि पोर्ट के लिए अटूट-एन्कोडेड है, एक उचित यूनिकोड एन्कोडिंग में इसे एनकोड करना सुनिश्चित करें। कभी-कभी इसका मतलब यह है कि डेटा का केवल एक हिस्सा, उदाहरण के लिए, UTF-8 को एन्कोड किया जाना चाहिए। कुछ भाग द्विआधारी डेटा (जैसे लंबाई सूचक) या कुछ और हो सकते हैं जो वर्ण एन्कोडिंग से गुजरना नहीं चाहिए, इसलिए कोई स्वचालित अनुवाद मौजूद नहीं है।

I / O सर्वर थोड़ा अलग तरह से व्यवहार करते हैं। टर्मिनलों से जुड़े I / O सर्वर (या stdout ) आमतौर पर एन्कोडिंग विकल्प की परवाह किए बिना यूनिकोड डेटा के साथ सामना कर सकते हैं। यह सुविधाजनक है जब कोई आधुनिक वातावरण की उम्मीद करता है लेकिन एक आर्कटिक टर्मिनल या पाइप पर लिखते समय दुर्घटना नहीं करना चाहता।

एक फ़ाइल में एक एन्कोडिंग विकल्प हो सकता है जो इसे आमतौर पर io मॉड्यूल (उदाहरण के लिए {encoding,utf8} ) द्वारा उपयोग करने योग्य बनाता है , लेकिन डिफ़ॉल्ट रूप से बाइट-उन्मुख फ़ाइल के रूप में खोला जाता है। file मॉड्यूल बाइट उन्मुख इसलिए केवल आईएसओ लैटिन -1 वर्णों कि मॉड्यूल का उपयोग कर लिखा जा सकता है है। io मॉड्यूल का उपयोग करें यदि यूनिकोड डेटा को फ़ाइल के साथ आउटपुट के encoding अलावा latin1 (बायोटेक एन्कोडिंग) के साथ किया जाए। यह थोड़ा भ्रमित है कि उदाहरण के लिए, के साथ खोली गई फ़ाइल को file:open(Name,[read,{encoding,utf8}]) ठीक से उपयोग करके नहीं पढ़ा जा सकता है file:read(File,N) , लेकिन io मॉड्यूल का उपयोग करके इसे यूनिकोड डेटा से पुनर्प्राप्त किया जा सकता है। कारण वही है file:read और file:write (और मित्र) विशुद्ध रूप से बाइट-ओरिएंटेड हैं, और होना चाहिए, क्योंकि यह टेक्स्ट फ़ाइलों के अलावा अन्य फ़ाइलों को एक्सेस करने का तरीका है, बाइट द्वारा। पोर्ट के साथ के रूप में, आप डेटा को "मैन्युअल रूप से" फ़ाइल में "मैन्युअल रूप से" unicode मोडकोडिंग (मॉड्यूल या बिट सिंटैक्स का उपयोग करके ) में लिख सकते हैं और फिर इसे एक बायटिव ( latin1 ) एन्कोडेड फ़ाइल पर आउटपुट कर सकते हैं ।

अनुशंसाएँ:

  • file बायटाइज एक्सेस ( {encoding,latin1} ) के लिए खोली गई फ़ाइलों के लिए मॉड्यूल का उपयोग करें ।

  • io किसी अन्य एन्कोडिंग (उदाहरण के लिए {encoding,uf8} ) के साथ फ़ाइलों तक पहुँचते समय मॉड्यूल का उपयोग करें ।

फ़ाइलों से Erlang सिंटैक्स पढ़ने वाले फ़ंक्शन coding: टिप्पणी को पहचानते हैं और इसलिए इनपुट पर यूनिकोड डेटा को संभाल सकते हैं। किसी फ़ाइल पर Erlang शब्द लिखते समय, आपको सलाह दी जाती है कि जब लागू हो तो ऐसी टिप्पणियाँ डालें:

$ erl +fna +pc unicode
Erlang R16B (erts-5.10.1) [source]  [async-threads:0] [hipe] [kernel-poll:false]

Eshell V5.10.1  (abort with ^G)
1> file:write_file("test.term",<<"%% coding: utf-8\n[{\"Юникод\",4711}].\n"/utf8>>).
ok
2> file:consult("test.term").   
{ok,[[{"Юникод",4711}]]}

3.12 विकल्पों का सारांश

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

यहां यूनिकोड को प्रभावित करने वाली सेटिंग का सारांश दिया गया है:

LANG और LC_CTYPE वातावरण चर

ऑपरेटिंग सिस्टम में भाषा सेटिंग मुख्य रूप से शेल को प्रभावित करती है। टर्मिनल (यानी, ग्रुप लीडर) {encoding, unicode} केवल तभी काम करता है जब पर्यावरण यह बताता है कि UTF-8 की अनुमति है। यह सेटिंग उस टर्मिनल के अनुरूप है जिसे आप उपयोग कर रहे हैं।

यदि फ़ाइल को झंडे के साथ शुरू किया जाता है +fna (जो Erlang / OTP 17.0 से डिफ़ॉल्ट है) , तो वातावरण फ़ाइल नाम की व्याख्या को भी प्रभावित कर सकता है ।

आप इसकी सेटिंग को कॉल करके चेक कर सकते हैं io:getopts() , जो आपको एक विकल्प सूची देता है जिसमें {encoding,unicode} या {encoding,latin1}

+pc { unicode | latin1 } झंडा लगाओ erl(1)

यह ध्वज प्रभावित करता है जिसे शेल में हेरास्टिक स्ट्रिंग का पता लगाने के दौरान और io / और प्रारूपण निर्देशों के io_lib:format साथ स्ट्रिंग डेटा के रूप में व्याख्या की जाती है , जैसा कि पहले वर्णित है। "~tp" ~tP

आप इस विकल्प को कॉल करके देख सकते हैं io:printable_range/0 , जो रिटर्न करता है unicode या latin1 । सेटिंग्स के io_lib:printable_list/1 अनुसार भविष्य (अपेक्षित) एक्सटेंशन के साथ संगत होने के लिए, यह जांचने के लिए उपयोग करें कि सेटिंग के अनुसार कोई सूची मुद्रण योग्य है या नहीं। यह फ़ंक्शन नई संभावित सेटिंग्स को ध्यान में रखता है io:printable_range/0

+fn { l | u | a } [{ w | i | e }] को ध्वजांकित करें erl(1)

यह ध्वज प्रभावित करता है कि फ़ाइल नाम की व्याख्या कैसे की जाए। पारदर्शी फ़ाइल नामकरण के साथ ऑपरेटिंग सिस्टम पर, यह यूनिकोड वर्णों में फ़ाइल नामकरण के लिए (और वर्ण> 255 वर्णों वाले फ़ाइल नाम की सही व्याख्या के लिए) निर्दिष्ट किया जाना चाहिए।

  • +fnl इसका मतलब है कि फाइलनाम की व्याख्या, जो कि यूटीएफ -8 फाइल नामकरण से पहले आईएसओ लैटिन -1 फाइलनेम का प्रतिनिधित्व करने का सामान्य तरीका था, व्यापक रूप से फैल गया।

  • +fnu इसका मतलब है कि फ़ाइलनाम UTF-8 में एन्कोड किए गए हैं, जो आजकल आम योजना है (हालांकि लागू नहीं)।

  • +fna आप स्वचालित रूप से के बीच चयन का मतलब है +fnl और +fnu वातावरण चर पर आधारित है, LANG और LC_CTYPE । यह वास्तव में आशावादी उत्तराधिकार है, कुछ भी एक उपयोगकर्ता को फाइल सिस्टम के समान एन्कोडिंग के साथ टर्मिनल के लिए लागू नहीं करता है, लेकिन यह आमतौर पर मामला है। यह सभी यूनिक्स जैसी ऑपरेटिंग सिस्टम पर डिफ़ॉल्ट है, सिवाय MacOS X के।

फ़ाइलनाम अनुवाद मोड को फ़ंक्शन के साथ पढ़ा जा सकता है file:native_name_encoding/0 , जो रिटर्न देता है latin1 (बायोटाइज एन्कोडिंग) या utf8

epp:default_encoding/0

यह फ़ंक्शन वर्तमान में जारी रिलीज़ में Erlang स्रोत फ़ाइलों (यदि कोई एन्कोडिंग टिप्पणी मौजूद नहीं है) के लिए डिफ़ॉल्ट एन्कोडिंग देता है। Erlang / OTP R16B में, latin1 (बायोटाइज एन्कोडिंग) वापस कर दिया गया था। Erlang / OTP 17.0 से, utf8 लौटा दिया गया है।

epp(3) मॉड्यूल में वर्णित टिप्पणियों का उपयोग करके प्रत्येक फ़ाइल की एन्कोडिंग को निर्दिष्ट किया जा सकता है ।

io:setopts/1,2 और झंडे -oldshell / -noshell

जब Erlang के साथ शुरू किया जाता है -oldshell या -noshell , के लिए I / O सर्वर standard_io डिफ़ॉल्ट रूप से bytewise एन्कोडिंग द्वारा सेट किया जाता है, जबकि एक इंटरेक्टिव शेल पर्यावरण चर को क्या कहता है।

आप फ़ंक्शन के साथ फ़ाइल या अन्य I / O सर्वर की एन्कोडिंग सेट कर सकते हैं io:setopts/2 । यह एक फ़ाइल खोलते समय भी सेट किया जा सकता है। टर्मिनल (या अन्य standard_io सर्वर) को बिना विकल्प के सेट करने का {encoding,utf8} तात्पर्य यह है कि डिवाइस के लिए UTF-8 एन्कोडेड वर्ण लिखे गए हैं, भले ही एर्लांग को शुरू किया गया हो या उपयोगकर्ता का वातावरण।

encoding किसी ज्ञात एन्कोडिंग में पाठ फ़ाइलों को लिखते या पढ़ते समय विकल्प के साथ फाइलें खोलना सुविधाजनक होता है।

आप encoding फ़ंक्शन के साथ I / O सर्वर के लिए सेटिंग पुनः प्राप्त कर सकते हैं io:getopts()

3.13 व्यंजनों

यूनिकोड के साथ शुरू होने पर, कोई अक्सर कुछ सामान्य मुद्दों पर ठोकर खाता है। यह खंड यूनिकोड डेटा से निपटने के कुछ तरीकों का वर्णन करता है।

बाइट ऑर्डर मार्क्स

टेक्स्ट फ़ाइलों में एन्कोडिंग की पहचान करने का एक सामान्य तरीका यह है कि पहले फाइल में बाइट ऑर्डर मार्क (BOM) लगाया जाए। BOM कोड बिंदु 16 है # FEFF शेष फ़ाइल की तरह ही इनकोड किया गया है। यदि ऐसी फाइल को पढ़ना है, तो पहले कुछ बाइट्स (एन्कोडिंग के आधार पर) पाठ का हिस्सा नहीं होते हैं। यह कोड बताता है कि एक ऐसी फ़ाइल कैसे खोलें जो माना जाता है कि BOM है, और फ़ाइलों को एन्कोडिंग और स्थिति को आगे अनुक्रमिक पढ़ने के लिए सेट करता है (अधिमानतः io मॉड्यूल का उपयोग करके )।

ध्यान दें कि त्रुटि से निपटने कोड से छोड़ा गया है:

open_bom_file_for_reading(File) ->
    {ok,F} = file:open(File,[read,binary]),
    {ok,Bin} = file:read(F,4),
    {Type,Bytes} = unicode:bom_to_encoding(Bin),
    file:position(F,Bytes),
    io:setopts(F,[{encoding,Type}]),
    {ok,F}.

फ़ंक्शन unicode:bom_to_encoding/1 कम से कम चार बाइट्स के बाइनरी से एन्कोडिंग की पहचान करता है। यह फ़ाइल के एन्कोडिंग को सेट करने के लिए उपयुक्त शब्द के साथ, बीओएम की बाइट की लंबाई के साथ लौटता है, ताकि फ़ाइल स्थिति तदनुसार सेट की जा सके। ध्यान दें कि फ़ंक्शन file:position/2 हमेशा बाइट-ऑफ़सेट पर काम करता है, ताकि बीओएम की बाइट लंबाई की आवश्यकता हो।

लिखने के लिए एक फ़ाइल खोलने के लिए और BOM को पहले रखना और भी सरल है:

open_bom_file_for_writing(File,Encoding) ->
    {ok,F} = file:open(File,[write,binary]),
    ok = file:write(File,unicode:encoding_to_bom(Encoding)),
    io:setopts(F,[{encoding,Encoding}]),
    {ok,F}.

फ़ाइल इन दोनों मामलों में है तो io मॉड्यूल का उपयोग करके सबसे अच्छा संसाधित किया जाता है, क्योंकि उस मॉड्यूल में फ़ंक्शन आईएसओ लैटिन -1 श्रेणी से परे कोड बिंदुओं को संभाल सकते हैं।

प्रारूपित I / O

यूनिकोड-जागरूक संस्थाओं को पढ़ने और लिखने के दौरान, यूनिकोड अनुवाद के लिए खोली गई फ़ाइल की तरह, आप संभवतः io मॉड्यूल या मॉड्यूल में फ़ंक्शन का उपयोग करके टेक्स्ट स्ट्रिंग्स को प्रारूपित करना चाहते हैं io_lib । पिछड़े अनुकूलता कारणों के लिए, ये फ़ंक्शन किसी भी सूची को एक स्ट्रिंग के रूप में स्वीकार नहीं करते हैं, लेकिन यूनिकोड ग्रंथों के साथ काम करते समय एक विशेष अनुवाद संशोधक की आवश्यकता होती है । संशोधक है t । जब s एक प्रारूपण स्ट्रिंग में चरित्र को नियंत्रित करने के लिए आवेदन किया जाता है , तो यह सभी यूनिकोड कोड बिंदुओं को स्वीकार करता है और बायनेरिज़ को UT-8 में होने की उम्मीद करता है:

1> io:format("~ts~n",[<<"åäö"/utf8>>]).
åäö
ok
2> io:format("~s~n",[<<"åäö"/utf8>>]).
åäö
ok

स्पष्ट रूप से, दूसरा io:format/2 अवांछित उत्पादन देता है, क्योंकि UTF-8 बाइनरी में नहीं है latin1 । पिछड़ी अनुकूलता के लिए, गैर-उपसर्ग नियंत्रण चरित्र s बायनेरिज़ में आईएसओ-लैटिन कोड -1 के बीट्यूज़-एन्कोडेड की अपेक्षा करता है और केवल कोड बिंदुओं की सूची होती है <256।

जब तक डेटा हमेशा सूचियों में रहता है, t तब तक किसी भी स्ट्रिंग के लिए संशोधक का उपयोग किया जा सकता है, लेकिन जब बाइनरी डेटा शामिल होता है, तो फ़ॉर्मेटिंग वर्णों का सही विकल्प बनाने के लिए देखभाल की जानी चाहिए। बायटिव-एनकोडेड बाइनरी को एक स्ट्रिंग के रूप में भी व्याख्या किया जाता है, और उपयोग करते समय भी मुद्रित किया जाता है ~ts , लेकिन इसे एक वैध यूटीएफ -8 स्ट्रिंग के लिए गलत किया जा सकता है। इसलिए ~ts नियंत्रण का उपयोग करने से बचें यदि बाइनरी में अटैच-एन्कोड किए गए वर्ण होते हैं न कि यूटीएफ -8।

कार्य io_lib:format/2 समान व्यवहार करता है। इसे पात्रों की एक गहरी सूची को लौटाने के लिए परिभाषित किया गया है और किसी भी डिवाइस पर आउटपुट के लिए बाइनरी डेटा को आउटपुट को आसानी से परिवर्तित किया जा सकता है erlang:list_to_binary/1 । जब अनुवाद संशोधक का उपयोग किया जाता है, तो सूची में, ऐसे वर्ण शामिल हो सकते हैं जो एक बाइट में संग्रहीत नहीं किए जा सकते। इसके बाद कॉल erlang:list_to_binary/1 विफल हो जाता है। हालाँकि, यदि आप जिस I / O सर्वर के साथ संवाद करना चाहते हैं, वह यूनिकोड-जागरूक है, तो दी गई सूची का उपयोग अभी भी सीधे किया जा सकता है:

$ erl +pc unicode
Erlang R16B (erts-5.10.1) [source] [async-threads:0] [hipe] [kernel-poll:false]

Eshell V5.10.1 (abort with ^G)
1> io_lib:format("~ts~n", ["Γιούνικοντ"]).
["Γιούνικοντ","\n"]
2> io:put_chars(io_lib:format("~ts~n", ["Γιούνικοντ"])).
Γιούνικοντ
ok

यूनिकोड स्ट्रिंग को यूनिकोड सूची के रूप में लौटाया जाता है, जिसे इस तरह से पहचाना जाता है, क्योंकि एरलैंग शेल यूनिकोड एन्कोडिंग का उपयोग करता है (और इसे प्रिंट किए जाने वाले सभी यूनिकोड वर्णों के साथ शुरू किया जाता है)। यूनिकोड सूची कार्य करने के लिए मान्य इनपुट है io:put_chars/2 , इसलिए डेटा को किसी भी यूनिकोड-सक्षम डिवाइस पर आउटपुट किया जा सकता है। यदि डिवाइस एक टर्मिनल है, तो वर्ण प्रारूप \x{ H में आउटपुट हैं ... } यदि एन्कोडिंग है latin1 । अन्यथा UTF-8 में (गैर-संवादात्मक टर्मिनल के लिए: "oldshell" या "noshell") या जो भी चरित्र को ठीक से दिखाने के लिए उपयुक्त है (एक इंटरैक्टिव टर्मिनल के लिए: नियमित शेल)।

तो, आप हमेशा standard_io डिवाइस पर यूनिकोड डेटा भेज सकते हैं । हालाँकि, फ़ाइलें केवल यूनिकोड कोड बिंदुओं को स्वीकार करती हैं, जो कि आईएसओ लैटिन -1 से परे है, अगर encoding वह किसी और चीज़ से सेट है latin1

UTF-8 की अनुमानी पहचान

हालांकि यह दृढ़ता से प्रोत्साहित किया जाता है कि बाइनरी डेटा में वर्णों का एन्कोडिंग प्रसंस्करण से पहले जाना जाता है, यह हमेशा संभव नहीं है। एक विशिष्ट लिनक्स सिस्टम पर, UTF-8 और ISO लैटिन -1 टेक्स्ट फ़ाइलों का मिश्रण होता है, और उनकी पहचान करने के लिए फाइलों में किसी भी BOMs होते हैं।

UTF-8 को इसलिए डिज़ाइन किया गया है कि 7-बिट ASCII रेंज से परे संख्या वाले ISO लैटिन -1 वर्णों को शायद ही कभी वैध माना जाता है जब UTF-8 को डिकोड किया जाता है। इसलिए आमतौर पर यह निर्धारित करने के लिए कि क्या कोई फ़ाइल UTF-8 में है या यदि वह आईएसओ लैटिन -1 (एक चरित्र प्रति बाइट) में कूटबद्ध है, तो यह निर्धारित करने के लिए हेयुरेटिक्स का उपयोग कर सकते हैं। unicode मॉड्यूल निर्धारित करने के लिए इस्तेमाल किया जा सकता डेटा UTF-8 के रूप में व्याख्या की जा सकती है:

heuristic_encoding_bin(Bin) when is_binary(Bin) ->
    case unicode:characters_to_binary(Bin,utf8,utf8) of
	Bin ->
	    utf8;
	_ ->
	    latin1
    end.

यदि आपके पास फ़ाइल सामग्री का पूर्ण बाइनरी नहीं है, तो आप इसके बजाय फ़ाइल के माध्यम से हिस्सा और भाग द्वारा जांच कर सकते हैं। {incomplete,Decoded,Rest} फ़ंक्शन से वापसी-ट्यूपल unicode:characters_to_binary/1,2,3 काम में आता है। फ़ाइल से पढ़े गए डेटा का एक हिस्सा से अधूरा बाकी अगले चंक से जुड़ा हुआ है और इसलिए हम UTF-8 एन्कोडिंग में बाइट्स के पढ़ने पर चरित्र सीमाओं की समस्या से बचते हैं:

heuristic_encoding_file(FileName) ->
    {ok,F} = file:open(FileName,[read,binary]),
    loop_through_file(F,<<>>,file:read(F,1024)).

loop_through_file(_,<<>>,eof) ->
    utf8;
loop_through_file(_,_,eof) ->
    latin1;
loop_through_file(F,Acc,{ok,Bin}) when is_binary(Bin) ->
    case unicode:characters_to_binary([Acc,Bin]) of
	{error,_,_} ->
	    latin1;
	{incomplete,_,Rest} ->
	    loop_through_file(F,Rest,file:read(F,1024));
	Res when is_binary(Res) ->
	    loop_through_file(F,<<>>,file:read(F,1024))
    end.

एक अन्य विकल्प UTF-8 एन्कोडिंग में पूरी फाइल को पढ़ने की कोशिश करना है और देखना है कि क्या यह विफल रहता है। यहां हमें फ़ंक्शन का उपयोग करके फ़ाइल पढ़ने की आवश्यकता है io:get_chars/3 , क्योंकि हमें वर्णों को एक कोड बिंदु> 255 के साथ पढ़ना होगा:

heuristic_encoding_file2(FileName) ->
    {ok,F} = file:open(FileName,[read,binary,{encoding,utf8}]),
    loop_through_file2(F,io:get_chars(F,'',1024)).

loop_through_file2(_,eof) ->
    utf8;
loop_through_file2(_,{error,_Err}) ->
    latin1;
loop_through_file2(F,Bin) when is_binary(Bin) ->
    loop_through_file2(F,io:get_chars(F,'',1024)).

UTF-8 बाइट्स की सूची

विभिन्न कारणों से, आपके पास कभी-कभी UTF-8 बाइट्स की एक सूची हो सकती है। यह यूनिकोड वर्णों का एक नियमित स्ट्रिंग नहीं है, क्योंकि प्रत्येक सूची तत्व में एक वर्ण नहीं है। इसके बजाय आपको "कच्चा" UTF-8 एन्कोडिंग मिलता है जो आपके पास बायनेरिज़ में है। यह आसानी से एक उचित यूनिकोड स्ट्रिंग को बाइट में पहले बाइट में परिवर्तित करके बाइनरी में परिवर्तित किया जाता है, और फिर यूटीएफ -8 एनकोडेड वर्णों के बाइनरी को यूनिकोड स्ट्रिंग में परिवर्तित किया जाता है:

utf8_list_to_string(StrangeList) ->
  unicode:characters_to_list(list_to_binary(StrangeList)).

डबल UTF-8 एन्कोडिंग

बायनेरिज़ के साथ काम करते समय, आप भयानक "डबल UTF-8 एन्कोडिंग" प्राप्त कर सकते हैं, जहां अजीब चरित्र आपके बायनेरी या फ़ाइलों में एन्कोड किए गए हैं। दूसरे शब्दों में, आप एक UTF-8 एनकोडेड बाइनरी प्राप्त कर सकते हैं जो दूसरी बार UTF-8 के रूप में एन्कोड किया गया है। एक सामान्य स्थिति वह है जहाँ आप एक फाइल को बाइट से पढ़ते हैं, लेकिन सामग्री पहले से ही UTF-8 है। यदि आप उदाहरण के लिए, उदाहरण के लिए, unicode मॉड्यूल, या विकल्प के साथ खोली गई फ़ाइल में लिखकर , यूटीएफ -8 को बाइट्स में परिवर्तित करते हैं {encoding,utf8} , तो आपके पास यूटीएफ -8 के रूप में एन्कोडेड इनपुट फ़ाइल में प्रत्येक बाइट है, मूल पाठ का प्रत्येक वर्ण नहीं। (एक चरित्र कई बाइट्स में एन्कोड किया जा सकता है)। यह सुनिश्चित करने के अलावा कि डेटा किस प्रारूप में इनकोड किया गया है, और इसके बाद कभी भी UTF-8 डेटा (संभवतः एक फाइल से बाइट को बाइट पढ़ें) को UTF-8 में परिवर्तित करने के अलावा इसके लिए कोई वास्तविक उपाय नहीं है।

अब तक की सबसे आम स्थिति, जहां ऐसा होता है, जब आप उचित यूनिकोड स्ट्रिंग्स के बजाय UTF-8 की सूची प्राप्त करते हैं, और फिर उन्हें एक बाइनरी या फ़ाइल में UTF-8 में कनवर्ट करते हैं:

wrong_thing_to_do() ->
  {ok,Bin} = file:read_file("an_utf8_encoded_file.txt"),
  MyList = binary_to_list(Bin), %% Wrong! It is an utf8 binary!
  {ok,C} = file:open("catastrophe.txt",[write,{encoding,utf8}]), 
  io:put_chars(C,MyList), %% Expects a Unicode string, but get UTF-8
                          %% bytes in a list!
  file:close(C). %% The file catastrophe.txt contains more or less unreadable
                 %% garbage!

सुनिश्चित करें कि आप जानते हैं कि एक स्ट्रिंग में बदलने से पहले बाइनरी में क्या होता है। यदि कोई अन्य विकल्प मौजूद नहीं है, तो आंकड़े देखें:

if_you_can_not_know() ->
  {ok,Bin} = file:read_file("maybe_utf8_encoded_file.txt"),
  MyList = case unicode:characters_to_list(Bin) of
    L when is_list(L) ->
      L;
    _ ->
      binary_to_list(Bin) %% The file was bytewise encoded
  end,
  %% Now we know that the list is a Unicode string, not a list of UTF-8 bytes
  {ok,G} = file:open("greatness.txt",[write,{encoding,utf8}]), 
  io:put_chars(G,MyList), %% Expects a Unicode string, which is what it gets!
  file:close(G). %% The file contains valid UTF-8 encoded Unicode characters!

Original text