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

RBS: रूबी का नया टाइप एनोटेशन सिस्टम समझाया गया

RBS रूबी के लिए एक नया टाइप सिंटैक्स फॉर्मेट लैंग्वेज है। RBS आपको .rbs एक्सटेंशन वाली नई फाइलों में अपने रूबी कोड में टाइप एनोटेशन जोड़ने की सुविधा देता है। ये कुछ इस तरह दिखते हैं:

class MyClass def my_method : (my_param: String) -> String end 

RBS के साथ टाइप एनोटेशन प्रदान करके आपको निम्न लाभ मिलते हैं:

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

लेकिन रुकिए! क्या पहले से ही Sorbet और Steep जैसे स्टेटिक टाइप चेकर्स मौजूद नहीं हैं?

हां, और वे बेहतरीन हैं! हालांकि, चार साल की चर्चा और कम्युनिटी द्वारा निर्मित कुछ टाइप चेकर्स के बाद, रूबी कमिटर टीम ने टाइप चेकर टूल्स बनाने के लिए कुछ मानकों को परिभाषित करने का समय सही समझा।

RBS आधिकारिक तौर पर एक भाषा है, और यह रूबी 3 के साथ अस्तित्व में आ रही है।

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

रूबी 3 इंस्टॉलेशन

यहां दिखाए गए उदाहरणों को फॉलो करने के लिए हमें रूबी 3 इंस्टॉल करना होगा।

आप इसे आधिकारिक निर्देशों का पालन करके या रूबी-बिल्ड के माध्यम से कर सकते हैं, यदि आपको कई रूबी वर्जन मैनेज करने की आवश्यकता है।

वैकल्पिक रूप से, आप अपने वर्तमान प्रोजेक्ट में सीधे rbs जेम भी इंस्टॉल कर सकते हैं:

gem install rbs 

स्टेटिक बनाम डायनामिक टाइपिंग

आगे बढ़ने से पहले, आइए इस कॉन्सेप्ट को स्पष्ट करते हैं। डायनामिकली टाइप्ड लैंग्वेज की तुलना स्टेटिक लैंग्वेज से कैसे की जाती है?

डायनामिकली टाइप्ड लैंग्वेज में, जैसे रूबी और जावास्क्रिप्ट, इंटरप्रेटर के लिए कोई पूर्वनिर्धारित डेटा टाइप नहीं होते हैं कि यदि रनटाइम के दौरान कोई निषिद्ध ऑपरेशन होता है तो कैसे आगे बढ़ना है।

यह स्टेटिक टाइपिंग से अपेक्षित चीज़ के बिल्कुल विपरीत है। स्टेटिकली टाइप्ड लैंग्वेज, जैसे जावा और C, कंपाइल टाइम के दौरान टाइप वेरिफाई करते हैं।

निम्नलिखित जावा कोड स्निपेट को रेफरेंस के रूप में लें:

int number = 0; number = "Hi, number!"; 

यह स्टेटिक टाइपिंग में संभव नहीं है, क्योंकि दूसरी लाइन एक एरर फेंकेगी:

error: incompatible types: String cannot be converted to int 

अब, वही उदाहरण रूबी में:

number = 0; number = "Hi, number!"; puts number // सफलतापूर्वक "Hi, number!" प्रिंट करता है 

रूबी में, एक वेरिएबल का टाइप ऑन-द-फ्लाई बदलता है, जिसका अर्थ है कि इंटरप्रेटर जानता है कि एक से दूसरे में डायनामिकली कैसे स्वैप करना है।

यह कॉन्सेप्ट आमतौर पर स्ट्रॉन्गली टाइप्ड बनाम वीकली टाइप्ड लैंग्वेज के साथ भ्रमित होता है।

रूबी न केवल एक डायनामिकली बल्कि स्ट्रॉन्गली टाइप्ड भाषा भी है, जिसका अर्थ है कि यह रनटाइम के दौरान एक वेरिएबल को अपना टाइप बदलने की अनुमति देता है। हालांकि, यह आपको क्रेजी टाइप मिक्सिंग ऑपरेशन करने की अनुमति नहीं देता है।

अगला उदाहरण लें (रूबी में) पिछले वाले से अनुकूलित:

number = 2; sum = "2" + 2; puts sum 

इस बार हम दो अलग-अलग टाइप के नंबरों (एक Integer और एक String) का योग करने का प्रयास कर रहे हैं। रूबी निम्नलिखित एरर फेंकेगा:

main.rb:2:in `+': no implicit conversion of Integer into String (TypeError) from main.rb:2:in `<main>' 

दूसरे शब्दों में, रूबी कह रहा है कि (संभावित रूप से) अलग-अलग टाइप वाले जटिल गणनाओं को करने का काम पूरी तरह से आपका है।

दूसरी ओर, जावास्क्रिप्ट, जो वीकली और डायनामिकली टाइप्ड है, वही कोड अलग परिणाम के साथ अनुमति देता है:

> number = 2 sum = "2" + 2 console.log(sum) > 22 // यह दोनों मानों को जोड़ देता है 

RBS, Sorbet से कैसे अलग है?

सबसे पहले, प्रत्येक द्वारा कोड एनोटेट करने के लिए अपनाए गए दृष्टिकोण से। जबकि Sorbet आपके कोड में स्पष्ट रूप से एनोटेशन जोड़कर काम करता है, RBS को केवल .rbs एक्सटेंशन वाली एक नई फाइल बनाने की आवश्यकता होती है।

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

इसके निर्माताओं के अनुसार, RBS का मुख्य लक्ष्य आपके रूबी प्रोग्राम्स की संरचना का वर्णन करना है। यह केवल क्लास/मेथड सिग्नेचर को परिभाषित करने पर केंद्रित है।

RBS स्वयं टाइप चेक नहीं कर सकता। इसका लक्ष्य टाइप चेकर्स (जैसे Sorbet और Steep) के लिए आधार के रूप में संरचना को परिभाषित करने तक सीमित है ताकि वे अपना काम कर सकें।

आइए एक साधारण रूबी इनहेरिटेंस का उदाहरण देखें:

class Badger def initialize(brand) @brand = brand end def brand? @brand end end class Honey < Badger def initialize(brand: "Honeybadger", sweet: true) super(brand) @sweet = sweet end def sweet? @sweet end end 

बहुत बढ़िया! बस दो क्लासेस कुछ एट्रिब्यूट्स और अनुमानित टाइप्स के साथ।

नीचे, हम एक संभावित RBS प्रतिनिधित्व देख सकते हैं:

class Brand attr_reader brand : String def initialize : (brand: String) -> void end class Honey < Brand @sweet : bool def initialize : (brand: String, ?sweet: bool) -> void def sweet? : () -> bool end 

काफी समान, है ना? यहां मुख्य अंतर टाइप्स हैं। उदाहरण के लिए, Honey क्लास का initialize मेथड एक String और एक boolean पैरामीटर प्राप्त करता है और कुछ भी वापस नहीं करता।

इस बीच, Sorbet टीम RBI (Sorbet का टाइप डेफिनिशन के लिए डिफ़ॉल्ट एक्सटेंशन) और RBS के बीच इंटरऑपरेबिलिटी की अनुमति देने वाले टूल्स बनाने पर मिलकर काम कर रही है।

लक्ष्य Sorbet और किसी भी टाइप चेकर के लिए यह समझने के लिए आधार तैयार करना है कि RBS की टाइप डेफिनिशन फाइलों का उपयोग कैसे किया जाए।

स्कैफोल्डिंग टूल

यदि आप भाषा के साथ शुरुआत कर रहे हैं और पहले से ही कुछ प्रोजेक्ट्स चल रहे हैं, तो यह अनुमान लगाना कठिन हो सकता है कि कहां और कैसे टाइपिंग शुरू करें।

इसे ध्यान में रखते हुए, रूबी टीम ने हमें rbs नामक एक बहुत उपयोगी CLI टूल प्रदान किया है जो मौजूदा क्लासेस के लिए टाइप्स को स्कैफोल्ड करता है।

उपलब्ध कमांड्स को सूचीबद्ध करने के लिए, बस कंसोल में rbs help टाइप करें और परिणाम देखें:

RBS: रूबी का नया टाइप एनोटेशन सिस्टम समझाया गया CLI टूल में उपलब्ध कमांड्स।

शायद सूची में सबसे महत्वपूर्ण कमांड prototype है क्योंकि यह प्रदान की गई सोर्स कोड फाइल के ASTs का विश्लेषण करके "अनुमानित" RBS कोड जनरेट करता है।

अनुमानित क्योंकि यह 100% प्रभावी नहीं है। चूंकि आपका लिगेसी कोड मुख्य रूप से अनटाइप्ड है, इसलिए इसका अधिकांश स्कैफोल्डेड कंटेंट उसी तरह आएगा। RBS कुछ टाइप्स का अनुमान नहीं लगा सकता यदि कोई स्पष्ट असाइनमेंट नहीं हैं, उदाहरण के लिए।

आइए एक और उदाहरण लें, इस बार तीन अलग-अलग क्लासेस के साथ एक कैस्केडेड इनहेरिटेंस शामिल है:

class Animal def initialize(weight) @weight = weight end def breathe puts "Inhale/Exhale" end end class Mammal < Animal def initialize(weight, is_terrestrial) super(weight) @is_terrestrial = is_terrestrial end def nurse puts "I'm breastfeeding" end end class Cat < Mammal def initialize(weight, n_of_lives, is_terrestrial: true) super(weight, is_terrestrial) @n_of_lives = n_of_lives end def speak puts "Meow" end end 

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

अब, इन टाइप्स को स्कैफोल्ड करने के लिए, आइए निम्न कमांड चलाएं:

rbs prototype rb animal.rb mammal.rb cat.rb 

आप जितनी चाहें उतनी रूबी फाइलें पास कर सकते हैं। इस एक्जीक्यूशन का परिणाम निम्नलिखित है:

class Animal def initialize: (untyped weight) -> untyped def breathe: () -> untyped end class Mammal < Animal def initialize: (untyped weight, untyped is_terrestrial) -> untyped def nurse: () -> untyped end class Cat < Mammal def initialize: (untyped weight, untyped n_of_lives, ?is_terrestrial: bool is_terrestrial) -> untyped def speak: () -> untyped end 

जैसा कि हमने अनुमान लगाया था, RBS उन अधिकांश टाइप्स को नहीं समझ सका जिनके लिए हम क्लासेस बनाते समय लक्ष्य कर रहे थे।

आपका अधिकांश काम मैन्युअल रूप से untyped रेफरेंसेस को वास्तविक टाइप्स में बदलना होगा। इसको बेहतर ढंग से पूरा करने के तरीके खोजने के उद्देश्य से कुछ चर्चाएं अभी कम्युनिटी में चल रही हैं।

मेटाप्रोग्रामिंग

जब मेटाप्रोग्रामिंग की बात आती है, तो rbs टूल इसकी डायनामिक प्रकृति के कारण ज्यादा मदद नहीं करेगा।

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

class Meta define_method :greeting, -> { puts 'Hi there!' } end Meta.new.greeting 

इस टाइप को स्कैफोल्ड करने का परिणाम निम्नलिखित होगा:

class Meta end 

डक टाइपिंग

रूबी ऑब्जेक्ट्स की प्रकृति (उनके टाइप्स) के बारे में ज्यादा चिंता नहीं करता है लेकिन इसकी परवाह करता है कि वे क्या करने में सक्षम हैं (वे क्या करते हैं)।

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

"यदि कोई ऑब्जेक्ट बत्तख की तरह व्यवहार करता है (बोलता है, चलता है, उड़ता है, आदि), तो वह एक बत्तख है"

दूसरे शब्दों में, रूबी हमेशा इसे बत्तख की तरह ट्रीट करेगा भले ही इसकी मूल परिभाषा और टाइप्स बत्तख को प्रतिबिंबित करने के लिए नहीं थे।

हालांकि, डक टाइपिंग कोड इम्प्लीमेंटेशन के विवरण को छिपा सकता है जो आसानी से ट्रिकी और खोजने/पढ़ने में कठिन बन सकते हैं।

RBS ने इंटरफेस टाइप्स की अवधारणा पेश की, जो मेथड्स का एक सेट है जो किसी ठोस क्लास या मॉड्यूल पर निर्भर नहीं करते हैं।

आइए पिछले एनिमल इनहेरिटेंस उदाहरण को लें और मान लें कि हम टेरेस्ट्रियल एनिमल्स के लिए एक नया हायरार्किकल लेवल जोड़ रहे हैं जिससे हमारा Cat इनहेरिट करेगा:

class Terrestrial < Animal def initialize(weight) super(weight) end def run puts "Running..." end end 

नॉन-टेरेस्ट्रियल चाइल्ड ऑब्जेक्ट्स को दौड़ने से रोकने के लिए, हम एक इंटरफेस बना सकते हैं जो ऐसी कार्रवाई के लिए विशिष्ट टाइप की जांच करता है:

interface _CanRun # `<<` ऑपरेटर की आवश्यकता है जो `Terrestrial` ऑब्जेक्ट को स्वीकार करता है। def <<: (Terrestrial) -> void end 

जब विशिष्ट रन मेथड पर RBS कोड को मैप किया जाता है, तो वह सिग्नेचर होगा:

def run: (_CanRun) -> void 

जब भी कोई टेरेस्ट्रियल ऑब्जेक्ट के अलावा कुछ भी मेथड में पास करने का प्रयास करता है, तो टाइप चेकर एरर लॉग करना सुनिश्चित करेगा।

यूनियन टाइप्स

रूबिस्ट्स के बीच अलग-अलग टाइप्स के मान रखने वाले एक्सप्रेशंस होना भी आम है।

def fly: () -> (Mammal | Bird | Insect) 

RBS पाइप ऑपरेटर के माध्यम से उन्हें जोड़कर यूनियन टाइप्स को समायोजित करता है।

मेथड ओवरलोडिंग

एक और आम प्रथा (कई प्रोग्रामिंग लैंग्वेज में वास्तव में) मेथड ओवरलोडिंग की अनुमति देना है, जिसमें एक क्लास में एक ही नाम के एक से अधिक मेथड हो सकते हैं लेकिन सिग्नेचर अलग होता है (जैसे टाइप्स या पैरामीटर्स की संख्या, उनका क्रम, आदि)।

एक उदाहरण लें जिसमें एक एनिमल अपने निकटतम विकासवादी चचेरे भाइयों को वापस कर सकता है:

def evolutionary_cousins: () -> Enumerator[Animal, void] | { (Animal) -> void } -> void 

इस तरह, RBS हमें स्पष्ट रूप से यह निर्धारित करने की अनुमति देता है कि कोई दिया गया एनिमल एक विकासवादी चचेरा भाई होगा या उनमें से एक गुच्छा।

TypeProf

समानांतर में, रूबी टीम ने TypeProf नामक एक नया प्रोजेक्ट भी शुरू किया है, एक एक्सपेरिमेंटल टाइप-लेवल रूबी इंटरप्रेटर जिसका उद्देश्य RBS कंटेंट का विश्लेषण करना और (कोशिश करना) जनरेट करना है।

यह एब्स्ट्रैक्ट इंटरप्रिटेशन द्वारा काम करता है और अभी भी बेहतर रिफाइनमेंट की दिशा में पहला कदम उठा रहा है, इसलिए प्रोडक्शन उद्देश्यों के लिए इसका उपयोग करते समय सावधान रहें।

इसे इंस्टॉल करने के लिए, बस अपने प्रोजेक्ट में जेम जोड़ें:

gem install typeprof 

ध्यान रखें कि इसके लिए 2.7 से अधिक रूबी वर्जन की आवश्यकता होती है।

निम्नलिखित Animal क्लास वर्जन लें:

class Animal def initialize(weight) @weight = weight end def die(age) if age > 50 true elsif age <= 50 false elsif age < 0 nil end end end Animal.new(100).die(65) 

मेथड age के अंदर क्या चल रहा है और उसी मेथड को आगे कॉल करने के आधार पर, TypeProf कोड में मैनिपुलेट किए गए टाइप्स को स्मार्टली अनुमान लगा सकता है।

जब आप typeprof animal.rb कमांड चलाते हैं, तो आउटपुट यह होना चाहिए:

## Classes class Animal @weight: Integer def initialize: (Integer weight) -> Integer def die: (Integer age) -> bool? end 

यह एक शक्तिशाली टूल है जो पहले से ही बहुत सारे कोड वाले प्रोजेक्ट्स के लिए बहुत कुछ प्रदान करता है।

VS Code इंटीग्रेशन

वर्तमान में, RBS के लिए फॉर्मेटिंग, संरचना जांच आदि के लिए बहुत सारे उपलब्ध VS Code प्लगइन्स नहीं हैं। विशेष रूप से क्योंकि यह अभी भी अपेक्षाकृत नया है।

हालांकि, यदि आप स्टोर में "RBS" खोजते हैं तो आपको ruby-signature नामक एक प्लगइन मिल सकता है जो सिंटैक्स हाइलाइटिंग में मदद करेगा, जैसा कि नीचे दिखाया गया है:

RBS: रूबी का नया टाइप एनोटेशन सिस्टम समझाया गया VS Code में RBS सिंटैक्स हाइलाइटिंग।

निष्कर्ष

RBS अभी बहुत नया है और पहले से ही सुरक्षित रूबी कोडबेस की दिशा में एक महत्वपूर्ण कदम दर्शाता है।

सामान्य रूप से, समय के साथ नए टूल्स और ओपन-सोर्स प्रोजेक्ट्स इसे सपोर्ट करने के लिए सामने आएंगे, जैसे रूबी ऑन रेल्स एप्लिकेशंस के लिए RBS फाइलें जनरेट करने के लिए RBS Rails।

भविष्य रूबी कम्युनिटी के लिए सुरक्षित और अधिक बग-मुक्त एप्लिकेशंस के साथ अद्भुत चीजें रखता है। इंतजार नहीं कर सकता इसे देखने के लिए!


  1. RBS: रूबी का नया टाइप एनोटेशन सिस्टम समझाया गया RBS: रूबी का नया टाइप एनोटेशन सिस्टम समझाया गया

    RBS रूबी के लिए एक नया टाइप सिंटैक्स फॉर्मेट लैंग्वेज है। RBS आपको .rbs एक्सटेंशन वाली नई फाइलों में अपने रूबी कोड में टाइप एनोटेशन जोड़ने की सुविधा देता है। ये कुछ इस तरह दिखते हैं: class MyClass def my_method : (my_param: String) -> String end RBS के साथ टाइप एनोटेशन प्रदान करके आपको निम्न लाभ

  1. रूबी के साथ इंसर्शन सॉर्ट में महारत: एक चरण-दर-चरण गाइड रूबी के साथ इंसर्शन सॉर्ट में महारत: एक चरण-दर-चरण गाइड

    नोट: यह रूबी के साथ विभिन्न सॉर्टिंग एल्गोरिदम को लागू करने पर एक श्रृंखला का भाग 4 है। भाग 1 ने बबल सॉर्ट का पता लगाया, भाग 2 ने सिलेक्शन सॉर्ट का पता लगाया, और भाग 3 ने मर्ज सॉर्ट का पता लगाया। जैसा कि हम डेटा को सॉर्ट करने के लिए विभिन्न पद्धतियों का पता लगाना जारी रखते हैं, हम इंसर्शन सॉर्ट की

  1. Ruby 2.6 में 9 प्रमुख संवर्द्धन का अन्वेषण Ruby 2.6 में 9 प्रमुख संवर्द्धन का अन्वेषण

    Ruby का एक नया संस्करण नई सुविधाओं और प्रदर्शन सुधारों के साथ आ रहा है। क्या आप परिवर्तनों के साथ बने रहना चाहेंगे? आइए एक नज़र डालते हैं! अंतहीन रेंज (Endless Ranges) Ruby 2.5 और पुराने संस्करण पहले से ही अंतहीन रेंज का एक रूप (Float::INFINITY के साथ) का समर्थन करते हैं, लेकिन Ruby 2.6 इसे अगले स्त