गतिशील प्रेषण

कंप्यूटर विज्ञान में, गतिशील प्रेषण एक बहुरूपता (कंप्यूटर विज्ञान) संचालन (विधि (कंप्यूटर प्रोग्रामिंग) या फ़ंक्शन) के कार्यान्वयन को रन टाइम (प्रोग्राम जीवनचक्र चरण) पर कॉल करने की प्रक्रिया है। यह सामान्यतः ऑब्जेक्ट ओरिएंटेड प्रोग्रामिंग (OOP) भाषाओं और प्रणालियों में कार्यरत है, और इसकी एक प्रमुख विशेषता मानी जाती है।

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

गतिशील प्रेषण स्थिर प्रेषण के विपरीत है, जिसमें एक बहुरूपी संचालन के कार्यान्वयन को संकलन समय पर चुना जाता है। गतिशील प्रेषण का उद्देश्य एक उपयुक्त कार्यान्वयन के चयन को तब तक टाला जाता है जब तक कि रन टाइम प्रकार का पैरामीटर (या एकाधिक पैरामीटर) ज्ञात न हो जाए। गतिशील विधि प्रेषण एक ऐसा तरीका है, जो प्रोग्राम के रनटाइम में ये तय करता है कि किसी ऑब्जेक्ट के रेफ़्रेन्स में कौनसा मेथड एक्सेक्यूटे होगा ना कि कम्पाइल टाइम में गतिशील विधि प्रेषण इसीलिए महत्वपूर्ण है क्योंकि यही वह तरीका है जिससे जावा रन टाइम बहुरूपता को कार्यान्वित करता है।

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

सिंगल और मल्टीपल प्रेषण
कॉल करने की विधि के किसी संस्करण का विकल्प या तो एक वस्तु पर या वस्तुओं के संयोजन पर आधारित हो सकता है। पहले वाले को सिंगल प्रेषण कहा जाता है और यह सामान्य ऑब्जेक्ट-ओरिएंटेड भाषाओं जैसे स्मॉलटाक, C++, जावा (प्रोग्रामिंग भाषा), सी शार्प (प्रोग्रामिंग लैंग्वेज), सी#, ऑब्जेक्टिव सी, स्विफ्ट (प्रोग्रामिंग भाषा), जावास्क्रिप्ट और सीधे समर्थित है। पायथन (प्रोग्रामिंग भाषा) इन और इसी तरह की भाषाओं में, एक समान सिंटैक्स के साथ डिवीजन (गणित) के लिए एक विधि कह सकते हैं

जहां पैरामीटर वैकल्पिक हैं। इसे डिविडेंड के लिए पैरामीटर डिवाइडर के साथ डिवाइड नामक संदेश भेजने के रूप में माना जाता है। विभाजक के प्रकार या मूल्य की उपेक्षा करते हुए केवल लाभांश के प्रकार (शायद तर्कसंगत, फ्लोटिंग पॉइंट, मैट्रिक्स) के आधार पर एक कार्यान्वयन चुना जाएगा।

इसके विपरीत, कुछ भाषाएँ ऑपरेंड के संयोजन के आधार पर विधियों या कार्यों को प्रेषित करती हैं; विभाजन प्रकरण में, लाभांश और भाजक के प्रकार एक साथ निर्धारित करते हैं कि कौन सा विभाजन संचालन किया जाएगा। इसे एकाधिक प्रेषण के रूप में जाना जाता है। एकाधिक प्रेषण का समर्थन करने वाली भाषाओं के उदाहरण कॉमन लिस्प, डायलन और जूलिया हैं।

गतिशील प्रेषण तंत्र
विभिन्न गतिशील प्रेषण तंत्रों के साथ एक भाषा लागू की जा सकती है। किसी भाषा द्वारा प्रदान किए गए गतिशील प्रेषण तंत्र के विकल्प काफी सीमा तक उन प्रोग्रामिंग प्रतिमानों को बदल देते हैं जो किसी भाषा में उपलब्ध हैं या उपयोग करने के लिए सबसे स्वाभाविक हैं।

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

कुछ भाषाएँ हाइब्रिड दृष्टिकोण प्रदान करती हैं।

गतिशील प्रेषण में सदैव एक ओवरहेड होता है इसलिए कुछ भाषाएँ विशेष तरीकों के लिए स्थैतिक प्रेषण की पेशकश करती हैं।

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

C++ कंपाइलर्स सामान्यतः वर्चुअल विधि तालिका (वी टेबल) नामक डेटा संरचना के साथ गतिशील प्रेषण को कार्यान्वित करते हैं जो किसी दिए गए वर्ग के लिए सदस्य फ़ंक्शन पॉइंटर्स के सेट के रूप में नाम-से-कार्यान्वयन मैपिंग को परिभाषित करता है। (यह विशुद्ध रूप से एक कार्यान्वयन विवरण है; C ++ विनिर्देश वी टेबलs का उल्लेख नहीं करता है।) उस प्रकार के उदाहरण तब इस तालिका में उनके उदाहरण डेटा के भाग के रूप में एक सूचक को संग्रहीत करेंगे। यह जटिल है जब एकाधिक वंशानुक्रम का उपयोग किया जाता है। चूंकि C++ देर से बाध्यकारी का समर्थन नहीं करता है, C++ ऑब्जेक्ट में वर्चुअल टेबल को रन-टाइम पर संशोधित नहीं किया जा सकता है, जो प्रेषण लक्ष्य के संभावित सेट को संकलन समय पर चुने गए सीमित सेट तक सीमित करता है।

टाइप ओवरलोडिंग C++ में गतिशील प्रेषण का उत्पादन नहीं करता है क्योंकि भाषा संदेश पैरामीटर के प्रकारों को औपचारिक संदेश नाम का हिस्सा मानती है। इसका मतलब यह है कि प्रोग्रामर जो संदेश नाम देखता है वह बाइंडिंग के लिए उपयोग किया जाने वाला औपचारिक नाम नहीं है।

Go और Rust कार्यान्वयन
Go (प्रोग्रामिंग भाषा), Rust (प्रोग्रामिंग भाषा) और निम (प्रोग्रामिंग भाषा) में, प्रारम्भिक बाइंडिंग के अधिक बहुमुखी रूपांतर का उपयोग किया जाता है। वी टेबल पॉइंटर्स को ऑब्जेक्ट रेफरेंस के साथ 'फैट पॉइंटर्स' (गो में 'अंतरापृष्ठ', या रस्ट में 'ट्रेट ऑब्जेक्ट्स') के रूप में ले जाया जाता है। यह अंतर्निहित डेटा संरचनाओं से समर्थित अंतरापृष्ठ को अलग करता है। प्रत्येक संकलित लाइब्रेरी को किसी प्रकार का सही ढंग से उपयोग करने के लिए समर्थित अंतरापृष्ठ की पूरी श्रृंखला को जानने की आवश्यकता नहीं है, केवल विशिष्ट व्यवहार्य लेआउट जिसकी उन्हें आवश्यकता होती है। कोड अलग-अलग अंतरापृष्ठ को अलग-अलग कार्यों के लिए डेटा के एक ही टुकड़े में पास कर सकता है। यह बहुमुखी प्रतिभा प्रत्येक वस्तु संदर्भ के साथ अतिरिक्त डेटा की कीमत पर आती है, जो कि समस्याग्रस्त है यदि ऐसे कई संदर्भों को लगातार संग्रहीत किया जाता है।फैट पॉइंटर शब्द केवल अतिरिक्त संबंधित जानकारी के साथ एक पॉइंटर (कंप्यूटर प्रोग्रामिंग) को संदर्भित करता है। अतिरिक्त जानकारी ऊपर वर्णित गतिशील प्रेषण के लिए एक व्यवहार्य सूचक हो सकती है, लेकिन अधिक सामान्य रूप से संबंधित वस्तु का आकार वर्णन करने के लिए एक टुकड़ा है।

स्मालटॉक कार्यान्वयन
स्मॉलटाक एक प्रकार-आधारित संदेश प्रेषण का उपयोग करता है। प्रत्येक उदाहरण में एक ही प्रकार होता है जिसकी परिभाषा में विधियाँ होती हैं। जब एक उदाहरण एक संदेश प्राप्त करता है, तो प्रेषण प्रकार के लिए संदेश-टू-मेथड मैप में संबंधित विधि को देखता है और फिर विधि को आमंत्रित करता है।

क्योंकि एक प्रकार में आधार प्रकार की श्रृंखला हो सकती है, यह लुक-अप महंगा हो सकता है। स्मॉलटाक के तंत्र का एक सरल कार्यान्वयन C++ की तुलना में काफी अधिक ओवरहेड प्रतीत होता है और यह ओवरहेड प्रत्येक ऑब्जेक्ट को प्राप्त होने वाले प्रत्येक संदेश के लिए खर्च किया जाएगा।

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

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

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

पाइथन (प्रोग्रामिंग लैंग्वेज), रूबी (प्रोग्रामिंग भाषा), ऑब्जेक्टिव-सी और ग्रूवी (प्रोग्रामिंग भाषा) सहित कई अन्य गतिशील रूप से टाइप की गई भाषाएँ समान दृष्टिकोण का उपयोग करती हैं।

 पायथन में उदाहरण 

C++ में उदाहरण

यह भी देखें

 * समारोह बहु-संस्करण
 * फंक्शन ओवरलोडिंग
 * संदेश देना
 * ओवरराइडिंग विधि
 * दोहरा प्रेषण
 * नाम बाइंडिंग

अग्रिम पठन

 * (NB. Something similar to "fat pointers" specifically for Intel's real-mode segment:offset addressing on x86 processors, containing both a deliberately denormalized pointer to a shared code entry point and some info to still distinguish the different callers in the shared code. While, in an open system, pointer-normalizing 3rd-party instances (in other drivers or applications) cannot be ruled out completely on public interfaces, the scheme can be used safely on internal interfaces to avoid redundant entry code sequences.)
 * 
 * (NB. Something similar to "fat pointers" specifically for Intel's real-mode segment:offset addressing on x86 processors, containing both a deliberately denormalized pointer to a shared code entry point and some info to still distinguish the different callers in the shared code. While, in an open system, pointer-normalizing 3rd-party instances (in other drivers or applications) cannot be ruled out completely on public interfaces, the scheme can be used safely on internal interfaces to avoid redundant entry code sequences.)
 *