रूबी के लिए आरबीएस एक नए प्रकार की सिंटैक्स प्रारूप भाषा का नाम है। RBS आपको .rbs नामक एक नए एक्सटेंशन के साथ फाइलों में अपने रूबी कोड में टाइप एनोटेशन जोड़ने देता है . वे इस तरह दिखते हैं:
class MyClass
def my_method : (my_param: String) -> String
end
RBS के साथ टाइप एनोटेशन प्रदान करने से आपको निम्न लाभ मिलते हैं:
- आपके कोडबेस की संरचना को परिभाषित करने का एक साफ और संक्षिप्त तरीका।
- कक्षाओं को सीधे बदलने के बजाय फ़ाइलों के माध्यम से अपने लीगेसी कोड में प्रकार जोड़ने का एक सुरक्षित तरीका।
- स्थिर और गतिशील प्रकार के चेकर्स के साथ सार्वभौमिक रूप से एकीकृत करने की क्षमता।
- विधि ओवरलोडिंग, डक टाइपिंग, डायनेमिक इंटरफेस, और बहुत कुछ से निपटने के लिए नई सुविधाएँ।
पर रुको! क्या पहले से ही शर्बत और खड़ी जैसे स्थिर प्रकार के चेकर नहीं हैं?
हाँ, और वे महान हैं! हालांकि, चार साल की चर्चा और मुट्ठी भर समुदाय-निर्मित टाइप चेकर्स के बाद, रूबी कमिटर टीम ने सोचा कि यह टाइप चेकर टूल्स के निर्माण के लिए कुछ मानकों को परिभाषित करने का समय है।
RBS आधिकारिक तौर पर एक भाषा है, और यह रूबी 3 के साथ जीवंत हो रही है।
साथ ही, रूबी की गतिशील रूप से टाइप की गई प्रकृति के साथ-साथ डक टाइपिंग और विधि ओवरलोडिंग जैसे सामान्य पैटर्न के कारण, सर्वोत्तम संभव दृष्टिकोण सुनिश्चित करने के लिए कुछ सावधानियां स्थापित की जा रही हैं, जिन्हें हम जल्द ही और अधिक विस्तार से देखेंगे।
रूबी 3 इंस्टॉल करें
यहां दिखाए गए उदाहरणों का पालन करने के लिए, हमें रूबी 3 स्थापित करने की आवश्यकता है।
आप इसे आधिकारिक निर्देशों का पालन करके या रूबी-बिल्ड के माध्यम से कर सकते हैं यदि आपको कई रूबी संस्करणों को प्रबंधित करने की आवश्यकता है।
वैकल्पिक रूप से, आप rbs
. भी इंस्टॉल कर सकते हैं सीधे अपने वर्तमान प्रोजेक्ट में मणि:
gem install rbs
स्थिर बनाम गतिशील टाइपिंग
आगे जाने से पहले, आइए इस अवधारणा को स्पष्ट करें। गतिशील रूप से टाइप की जाने वाली भाषाएं स्थिर भाषाओं की तुलना में कैसे होती हैं?
रूबी और जावास्क्रिप्ट जैसी गतिशील रूप से टाइप की जाने वाली भाषाओं में, दुभाषिया के लिए कोई पूर्वनिर्धारित डेटा प्रकार नहीं है जो यह समझ सके कि रनटाइम के दौरान निषिद्ध ऑपरेशन होने की स्थिति में कैसे आगे बढ़ना है।
यह स्थिर टाइपिंग से अपेक्षित अपेक्षा के विपरीत है। जावा और सी जैसी सांख्यिकीय रूप से टाइप की गई भाषाएं संकलन समय के दौरान प्रकारों को सत्यापित करती हैं।
निम्नलिखित जावा कोड स्निपेट को संदर्भ के रूप में लें:
int number = 0;
number = "Hi, number!";
स्थिर टाइपिंग में यह संभव नहीं है, क्योंकि दूसरी पंक्ति में एक त्रुटि होगी:
error: incompatible types: String cannot be converted to int
अब, रूबी में वही उदाहरण लें:
number = 0;
number = "Hi, number!";
puts number // Successfully prints "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>'
दूसरे शब्दों में, रूबी का यह कहना कि (संभवतः) विभिन्न प्रकार की जटिल गणनाएँ करने का काम सब आपका है।
दूसरी ओर, JavaScript, जो कमजोर रूप से और . है गतिशील रूप से टाइप किया गया, एक ही कोड को एक अलग परिणाम के साथ अनुमति देता है:
> number = 2
sum = "2" + 2
console.log(sum)
> 22 // it concatenates both values
आरबीएस शर्बत से कैसे भिन्न है?
सबसे पहले, उस दृष्टिकोण से जो हर एक कोड को एनोटेट करने के लिए लेता है। जबकि सॉर्बेट आपके पूरे कोड में स्पष्ट रूप से एनोटेशन जोड़कर काम करता है, आरबीएस को केवल .rbs के साथ एक नई फ़ाइल के निर्माण की आवश्यकता होती है। विस्तार।
इसका प्राथमिक लाभ तब होता है जब हम लीगेसी कोडबेस के माइग्रेशन के बारे में सोचते हैं। चूंकि आपकी मूल फ़ाइलें प्रभावित नहीं होंगी, इसलिए अपने प्रोजेक्ट में RBS फ़ाइलों को अपनाना अधिक सुरक्षित है।
इसके रचनाकारों के अनुसार, RBS का मुख्य लक्ष्य है संरचना का वर्णन करना आपके रूबी कार्यक्रमों की। यह केवल वर्ग/विधि हस्ताक्षरों को परिभाषित करने पर केंद्रित है।
आरबीएस स्वयं चेक टाइप नहीं कर सकता। इसका लक्ष्य टाइप चेकर्स (जैसे शर्बत और खड़ी) को अपना काम करने के लिए एक आधार के रूप में संरचना को परिभाषित करने तक ही सीमित है।
आइए एक साधारण रूबी विरासत का उदाहरण देखें:
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
महान! कुछ विशेषताओं और अनुमानित प्रकारों के साथ केवल दो वर्ग।
नीचे, हम एक संभावित आरबीएस प्रतिनिधित्व देख सकते हैं:
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
बहुत समान, है ना? यहाँ प्रमुख अंतर प्रकार है। initialize
Honey
. की विधि वर्ग, उदाहरण के लिए, एक String
. प्राप्त करता है और एक boolean
पैरामीटर और कुछ भी नहीं देता है।
इस बीच, सॉर्बेट टीम आरबीआई (टाइप डेफिनिशन के लिए सॉर्बेट का डिफॉल्ट एक्सटेंशन) और आरबीएस के बीच इंटरऑपरेबिलिटी की अनुमति देने के लिए टूल्स के निर्माण पर मिलकर काम कर रही है।
लक्ष्य यह समझने के लिए कि आरबीएस की टाइप डेफिनिशन फाइलों का उपयोग कैसे किया जाए, शर्बत और किसी भी प्रकार के चेकर के लिए आधार तैयार करना है।
मचान उपकरण
अगर आप भाषा से शुरुआत कर रहे हैं और पहले से ही कुछ प्रोजेक्ट चल रहे हैं, तो यह अनुमान लगाना मुश्किल हो सकता है कि चीजों को कहां और कैसे टाइप करना शुरू करें।
इसे ध्यान में रखते हुए, रूबी टीम ने हमें rbs
. नामक एक बहुत ही उपयोगी CLI टूल प्रदान किया है मौजूदा वर्गों के लिए मचान प्रकारों के लिए।
उपलब्ध कमांड को सूचीबद्ध करने के लिए, बस rbs help
. टाइप करें कंसोल में और परिणाम की जांच करें:
सीएलआई टूल में उपलब्ध कमांड।
शायद सूची में सबसे महत्वपूर्ण कमांड है prototype
चूंकि यह "अनुमानित" आरबीएस कोड उत्पन्न करने के लिए एक परम के रूप में प्रदान की गई स्रोत कोड फ़ाइल के एएसटी का विश्लेषण करता है।
अनुमानित क्योंकि यह 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 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
जैसा कि हमने अनुमान लगाया है, आरबीएस उन अधिकांश प्रकारों को नहीं समझ सकता है जिनका लक्ष्य हमने कक्षाएं बनाते समय रखा था।
आपका अधिकांश काम 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
# Requires `<<` operator which accepts `Terrestrial` object.
def <<: (Terrestrial) -> void
end
RBS कोड को विशिष्ट रन विधि से मैप करते समय, वह हस्ताक्षर होगा:
def run: (_CanRun) -> void
जब भी कोई व्यक्ति स्थलीय वस्तु के अलावा कुछ भी पास करने की कोशिश करता है, तो टाइप चेकर त्रुटि को लॉग करना सुनिश्चित करेगा।
संघ प्रकार
रूबीवादियों के बीच विभिन्न प्रकार के मूल्यों वाले भावों का होना भी आम है।
def fly: () -> (Mammal | Bird | Insect)
RBS यूनियन प्रकारों को केवल पाइप . के माध्यम से जोड़कर उन्हें समायोजित करता है ऑपरेटर।
विधि ओवरलोडिंग
एक अन्य सामान्य अभ्यास (वास्तव में कई प्रोग्रामिंग भाषाओं में) विधि ओवरलोडिंग की अनुमति देना है, जिसमें एक वर्ग में एक ही नाम के साथ एक से अधिक विधियाँ हो सकती हैं, लेकिन हस्ताक्षर भिन्न होते हैं (जैसे कि प्रकार या पैरा की संख्या, उनका क्रम, आदि। )।
आइए एक उदाहरण लेते हैं जिसमें एक जानवर अपने निकटतम विकासवादी चचेरे भाई को वापस कर सकता है:
def evolutionary_cousins: () -> Enumerator[Animal, void] | { (Animal) -> void } -> void
इस तरह, आरबीएस हमें स्पष्ट रूप से यह निर्धारित करने की अनुमति देता है कि किसी दिए गए जानवर का एक एकल विकासवादी चचेरा भाई होगा या उनमें से एक गुच्छा होगा।
TypeProf
समानांतर में, रूबी टीम ने टाइपप्रोफ नामक एक नई परियोजना भी शुरू की है, जो एक प्रयोगात्मक प्रकार-स्तरीय रूबी दुभाषिया है जिसका उद्देश्य आरबीएस सामग्री का विश्लेषण करना और (कोशिश करना) करना है।
यह अमूर्त व्याख्या द्वारा काम करता है और अभी भी बेहतर परिशोधन की दिशा में पहला कदम उठा रहा है, इसलिए उत्पादन उद्देश्यों के लिए इसका उपयोग करते समय सावधान रहें।
इसे स्थापित करने के लिए, बस अपने प्रोजेक्ट में रत्न जोड़ें:
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
यह एक शक्तिशाली टूल है जिसमें उन परियोजनाओं के लिए बहुत कुछ है, जिनमें पहले से ही बहुत सारे कोड चल रहे हैं।
वीएस कोड एकीकरण
वर्तमान में, स्वरूपण, संरचना जाँच आदि के लिए RBS से निपटने के लिए बहुत सारे उपलब्ध VS कोड प्लगइन्स उपलब्ध नहीं हैं। विशेष रूप से क्योंकि यह अभी भी अपेक्षाकृत नया है।
हालांकि, अगर आप स्टोर में "आरबीएस" के लिए खोज करते हैं तो आपको रूबी-सिग्नेचर नामक एक प्लगइन मिल सकता है। जो सिंटैक्स हाइलाइटिंग में मदद करेगा, जैसा कि नीचे दिखाया गया है:
वीएस कोड में आरबीएस सिंटैक्स हाइलाइटिंग।
निष्कर्ष
RBS इतना ताज़ा है और पहले से ही सुरक्षित रूबी कोडबेस की दिशा में एक महत्वपूर्ण कदम का प्रतिनिधित्व करता है।
आम तौर पर, समय के साथ नए उपकरण और ओपन-सोर्स प्रोजेक्ट इसे वापस करने के लिए उठेंगे, जैसे कि रूबी ऑन रेल्स अनुप्रयोगों के लिए आरबीएस फाइलें बनाने के लिए आरबीएस रेल।
भविष्य में रूबी समुदाय के लिए सुरक्षित और अधिक बग-मुक्त अनुप्रयोगों के साथ अद्भुत चीजें हैं। इसे देखने के लिए इंतजार नहीं कर सकता!