Computer >> कंप्यूटर ट्यूटोरियल >  >> प्रोग्रामिंग >> Ruby

रूबी C एक्सटेंशन में आर्गुमेंट पार्सिंग में महारत: चरण-दर-चरण मार्गदर्शिका

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

इस वजह से, रूबी के आर्गुमेंट बहुत लचीले हैं, जो हमें अपने API को बहुत स्पष्ट रूप से व्यक्त करने देता है। लेकिन इसके साथ एक कमी आती है: रूबी C एक्सटेंशन डेवलपर्स के लिए पार्स करना काफी कठिन है!

इस लेख में, हम C में लिखे गए एक जटिल रूबी API को सेट करने के दो तरीकों से गुजरेंगे:

  • rb_define_method के साथ और rb_scan_args से इसे पार्स करना
  • रूबी इंटरफेस का उपयोग करना

शुरू करते हैं!

C और रूबी: एक परिचय

जैसा कि उल्लेख किया गया है, रूबी C एक्सटेंशन डेवलपर्स के लिए पार्स करना कठिन है।

उदाहरण के लिए:

 

C की सुंदरता, वह भाषा जिसमें रूबी लिखी गई है, इसकी सादगी से आती है, जिसमें इसके फंक्शन पैरामीटर्स भी शामिल हैं:

  • <डेटा-टाइप> <वेरिएबल-आइडेंटिफायर>
  • वेरिएडिक आर्गुमेंट्स के लिए ...।

ये आपको एक कोडबेस को बनाए रखने में मदद करेंगे जो समझने में बहुत कठिन नहीं है।

यहां C फंक्शन को परिभाषित करने का सबसे जटिल तरीका है:

 

जब आप अपने रूबी कोडबेस के लिए C एक्सटेंशन कोड करते हैं, तो आप समझना शुरू कर देंगे कि जटिलता कहां शुरू होती है। लेकिन चिंता न करें — रूबी MRI डेवलपर्स ने हमें कवर किया है।

रूबी C एक्सटेंशन में सरल मेथड परिभाषा

हम एक मेथड से शुरू करेंगे जिसे आपको किसी बिंदु पर उपयोग करना होगा, rb_define_method।

आप इस रेपो में कोड उदाहरणों के साथ भी अनुसरण कर सकते हैं।

यहां rb_define_method का सिग्नेचर है:

 

और रूबी के extension.rdoc के अनुसार:

argc आर्गुमेंट्स की संख्या है। यदि argc -1 है, तो फंक्शन को 3 आर्गुमेंट्स प्राप्त होंगे: argc, argv, और self। यदि argc -2 है, तो फंक्शन को 2 आर्गुमेंट्स प्राप्त होंगे, self और args, जहां args मेथड आर्गुमेंट्स का एक रूबी ऐरे है।

संक्षेप में:

 

इसलिए यदि आपका API केवल निश्चित पैरामीटर लंबाई वाले मेथड्स से बना है, या केवल एक वेरिएडिक पैरामीटर (def foo(*bar)), तो आगे न पढ़ें — आपका काम हो गया! यदि आप अपने API को कॉल करने का एक समृद्ध तरीका चाहते हैं, तो कृपया, मेरे मेहमान बनें।

वैसे, यदि आप rb_define_method पर अधिक शामिल उदाहरण चाहते हैं, तो मैं आपको पीटर झू के लेख 'Defining Methods' पढ़ने का सुझाव देता हूं।

रूबी C API इंटर्नल्स का उपयोग

तो, आइए अपने उपयोग के मामले पर वापस जाएं: जटिल आर्गुमेंट्स को पार्स करना। सौभाग्य से, कुछ टूल्स हैं जो हमारी मदद कर सकते हैं।

लेकिन पहले, आइए केवल rb_define_method का उपयोग करने की सीमाएं देखें।

rb_define_method की कमियां

ब्लॉक आर्गुमेंट्स का कोई उल्लेख नहीं

एक सीमा यह है कि rb_define_method कभी भी ब्लॉक आर्गुमेंट्स का उल्लेख नहीं करता। उन पर विचार नहीं किया जाता, क्योंकि रूबी के लिए यह वास्तव में मायने नहीं रखता कि आप एक ब्लॉक पास करते हैं। आप अभी भी यह सुनिश्चित कर सकते हैं कि rb_block_given_p या rb_need_block का उपयोग करके एक ब्लॉक पास किया गया है। उस विषय पर पीटर झू के लेख में अधिक है।

आर्गुमेंट्स भिन्न हो सकते हैं

एक और महत्वपूर्ण सीमा यह है कि आर्गुमेंट्स भिन्न हो सकते हैं, लेकिन मेथड कॉल स्वयं इतना प्रतिबंधित नहीं है। इसलिए, यदि आप चाहते हैं कि आपका API def foo(bar, *baz) जैसा हो, तो आपको अपने आर्गुमेंट्स को पार्स करना होगा। उस रास्ते पर आपकी मदद करने के लिए कुछ मेथड्स हैं। rb_check_arity एक है जिसका आप उपयोग कर सकते हैं, rb_define_method के -1 संस्करण के साथ।

यहां फंक्शन सिग्नेचर है:

 

कीवर्ड आर्गुमेंट्स

एक आखिरी सीमा जिससे हम गुजरेंगे वह है कीवर्ड आर्गुमेंट्स का उपयोग। और मैंने इसे अंत के लिए रखा, क्योंकि यह इस लेख का मूल होगा।

हम कीवर्ड आर्गुमेंट्स को सही ढंग से पार्स करने से पहले उन्हें पुनः प्राप्त करना होगा। सौभाग्य से, रूबी C API इसके लिए एक मेथड के साथ आता है, rb_scan_args।

यहां rb_scan_args का सिग्नेचर है:

 

आप rb_scan_args को rb_define_method द्वारा दिए गए argc और argv पास करते हैं — एक स्ट्रिंग जो बताती है कि आर्गुमेंट्स को कैसे पार्स किया जाना चाहिए (fmt) और उन आर्गुमेंट्स के लिए रिसीवर। वहां जाएं, रूबी के आर्गुमेंट्स की सारी जटिलता एक लाइन में पार्स हो गई! खैर, लगभग।

आप extension.rdoc को संदर्भित कर सकते हैं कि fmt कैसे लिखा जाना चाहिए, इसका औपचारिक प्रतिनिधित्व के लिए, हालांकि हम नीचे दिए गए उदाहरणों में इसे आंशिक रूप से कवर करेंगे।

एक फंक्शन लिखें और पार्स करें: एक उदाहरण

इस लेख के बाकी हिस्से के लिए, आइए मान लें कि हम यह फंक्शन लिखना चाहते हैं:

 

rb_scan_args का उपयोग करके इसे पार्स करना इस तरह दिखेगा:

 

"1*:" गिबरिश का अर्थ है:

  • 1: एक आवश्यक पोजिशनल आर्गुमेंट
  • *: कोई भी मात्रा में पोजिशनल आर्गुमेंट्स जो आवश्यक नहीं हैं
  • :: अंत में कीवर्ड आर्गुमेंट्स

कीवर्ड आर्गुमेंट्स पार्स करें

अब हमने मेथड को प्रतिबंधित कर दिया है, दुर्भाग्य से, हम अभी तक नहीं कर पाए हैं। हमारा वर्तमान API def voronoi_diagram(envelope, *polygons, **kwargs) है।

अंत में, हमें उन कीवर्ड आर्गुमेंट्स को rb_get_kwargs का उपयोग करके पार्स करना होगा।

 

आपको कुछ आवश्यक और वैकल्पिक आर्गुमेंट्स चुनने होंगे। एक बार हो जाने पर, आप table का उपयोग करके रूबी को उन आर्गुमेंट्स के नाम बताते हैं, और परिणाम को एक ऐरे (values) में स्टोर करते हैं।

 

वहां आपके पास है! केवल C का उपयोग करके एक जटिल रूबी मेथड, पार्स किया गया। हालांकि, यदि यह आपके लिए बहुत जटिल है, तो एक और विकल्प है।

रूबी इंटरफेस का उपयोग

समस्या को संभालने का दूसरा तरीका वास्तव में रूबी के सिंटैक्स का सीधे उपयोग करना और पार्सिंग को रूबी चरण में करना है।

 

इसके साथ, आप सीधे rb_define_method के तीसरे रूप का उपयोग कर सकते हैं, एक C मेथड के लिए जो इस तरह दिखता है:

 

और वहां आपके पास है — आप एक सुंदर समाधान के साथ समस्या से पूरी तरह बचते हैं जो वास्तव में रूबी कार्यान्वयन में कुछ मेथड्स के लिए उपयोग किया जाता है ( Primitive क्लास के साथ)।

हालांकि MRI द्वारा उपयोग की जाने वाली क्लास काफी जटिल है और स्वयं C उत्पन्न करती है, हम इससे प्रेरित हो सकते हैं।

आइए एक ऑब्जेक्ट बनाएं और अपने मेथड्स को प्लग करें ताकि हमारे API के उपयोगकर्ताओं के लिए एक दृश्यमान c_voronoi_diagram न हो:

 
 

RGeo के कोडबेस में इस क्लास के वास्तविक उपयोग के मामले को देखें।

आर्गुमेंट्स पार्स करना: मुझे किस मेथड का उपयोग करना चाहिए?

यह रेपो C में लिखे गए एक जटिल रूबी API को सेट करने के दो तरीकों को प्रदर्शित करता है — संक्षेप में:

  • rb_define_method के साथ और rb_scan_args से इसे पार्स करना
  • रूबी इंटरफेस का उपयोग करना

जब हम प्रदर्शन के मामले में दोनों समाधानों की तुलना करते हैं, तो वे लगभग बराबर हैं (मेरे M1 पर औसतन रूबी पार्सिंग 1.02 गुना तेज है)। इससे ज्यादा फर्क नहीं पड़ता।

RGeo लाइब्रेरी में, हमारी पहली डिजाइन पसंद एक ऐसा API रखना था जो केवल वेरिएडिक लंबाई के आर्गुमेंट्स का उपयोग करता हो। कोई कीवर्ड नहीं, कोई ब्लॉक नहीं। यह बहुत सीमित हो सकता है, और अब हम अधिक जटिल आर्गुमेंट्स की अनुमति देने के लिए Primitive तरीके का उपयोग कर रहे हैं।

रूबी इंटरफेस का उपयोग करने के लाभ

मेरी सलाह है कि कई कारणों से रूबी इंटरफेस का उपयोग करें, जिनमें शामिल हैं:

  • कोड का आकार छोटा होता है
  • परिवर्तन करना आसान होता है

कुल मिलाकर, यह आपके कोडबेस को पढ़ने के अनुभव को सरल बनाता है।

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

rb_define_method का उपयोग करने के लाभ

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

यह सब आपके उपयोग के मामले के लिए सर्वोत्तम विकल्प खोजने के बारे में है।

समापन

इस पोस्ट में, हमने आपके रूबी C एक्सटेंशन में आर्गुमेंट्स पार्स करने के दो मेथड्स का पता लगाया — rb_define_method का उपयोग करना (इसकी सीमाओं को संक्षेप में देखते हुए) और इसे rb_scan_args से पार्स करना और रूबी इंटरफेस का उपयोग करना।

यदि आप C एक्सटेंशन के बारे में अधिक पढ़ना चाहते हैं, तो मैं अनुशंसा करता हूं:

  • Building a Ruby C Extension From Scratch
  • A Rubyist's Walk Along the C-side
  • Working with ruby C extensions on Mac

और आपके लिए मेरी अंतिम सलाह: RGeo देखें। यह सक्रिय विकास में एक व्यापक रूप से उपयोग किया जाने वाला C एक्सटेंशन कोडबेस है। मेरे अधिकांश उदाहरण यहीं से आते हैं।

हैप्पी कोडिंग!

P.S. यदि आप रूबी मैजिक पोस्ट को प्रेस से बाहर आते ही पढ़ना चाहते हैं, तो हमारे रूबी मैजिक न्यूज़लेटर की सदस्यता लें और कभी भी एक भी पोस्ट मिस न करें!

रूबी C एक्सटेंशन में आर्गुमेंट पार्सिंग में महारत: चरण-दर-चरण मार्गदर्शिका

यूलिस बुओनोमो

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

यूलिस बुओनोमो के सभी लेख


  1. JavaScript - HTML बटन पर क्लिक करने पर अलर्ट बनाएं JavaScript - HTML बटन पर क्लिक करने पर अलर्ट बनाएं

    बटन पर क्लिक करने पर अलर्ट फायर करने के लिए, addEventListener() का उपयोग करें। मान लीजिए HTML वेब पेज पर हमारा बटन निम्नलिखित है: Please Press Me उदाहरण निम्नलिखित कोड देखें: Document Please Press Me var pressedButton = document.getElementsByTagName(button)[0]; pressedButton

  1. Tkinter का उपयोग करके फ्रेम के बीच में ऑब्जेक्ट्स कैसे रखें? Tkinter का उपयोग करके फ्रेम के बीच में ऑब्जेक्ट्स कैसे रखें?

    फ्रेम के बीच में ऑब्जेक्ट्स रखने के लिए, हम place मेथड का उपयोग कर सकते हैं। आइए एक उदाहरण लेते हैं और देखते हैं कि यह कैसे किया जाता है।चरणआवश्यक लाइब्रेरी इम्पोर्ट करें और Tkinter फ्रेम का एक इंस्टेंस बनाएं।win.geometry मेथड का उपयोग करके फ्रेम का आकार सेट करें।अगला, एक बटन बनाएं और इसे लेबल करें।

  1. लिनक्स शेल स्क्रिप्टिंग: वेरिएबल्स पर गहन नज़र – भाग 9 लिनक्स शेल स्क्रिप्टिंग: वेरिएबल्स पर गहन नज़र – भाग 9

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