टाइप कोएर्सन एक ऑब्जेक्ट के टाइप को उसके मान के साथ दूसरे टाइप में बदलना है। उदाहरण के लिए, #to_s के साथ एक Integer को String में बदलना या #to_i के साथ एक Float को Integer में बदलना। शायद कम ज्ञात #to_str और #to_int मेथड्स जो कुछ ऑब्जेक्ट्स लागू करते हैं, पहली नज़र में वही करते हैं, लेकिन कुछ अंतर हैं।
इस ऐपसिग्नल अकादमी संस्करण में, हम रूबी में एक्सप्लिसिट कास्टिंग और इम्प्लिसिट कोएर्सन टाइप्स में गोता लगाएंगे, जबकि संक्षेप में टाइपकास्टिंग एक्टर्स को छूएंगे। हम दोनों मेथड्स के बीच अंतर को कवर करेंगे, और चर्चा करेंगे कि उनका उपयोग कैसे किया जाता है।
आइए पहले देखें कि हम आमतौर पर रूबी में एक्सप्लिसिट कास्टिंग हेल्पर्स के साथ मानों को विभिन्न टाइप्स में कैसे कोएर्स करते हैं।
एक्सप्लिसिट कास्टिंग हेल्पर्स
सबसे आम कास्टिंग हेल्पर्स #to_s, #to_i, #to_a और #to_h हैं। ये एक्सप्लिसिट कास्टिंग मेथड्स हैं। वे हमें एक मान को एक टाइप से दूसरे में आसानी से बदलने में मदद करते हैं।
एक्सप्लिसिट हेल्पर्स एक स्पष्ट वादे के साथ आते हैं। जब भी किसी ऑब्जेक्ट पर #to_s कहा जाता है, तो यह हमेशा एक स्ट्रिंग लौटाएगा, भले ही ऑब्जेक्ट वास्तव में स्ट्रिंग में अच्छी तरह से कन्वर्ट न हो। यह माइकल कीटन को बैटमैन के रूप में कास्ट करने जैसा है। आपको एक बैटमैन मिलेगा, भले ही एक कॉमेडी एक्टर विशेष रूप से भूमिका के लिए उपयुक्त न हो।
रूबी रूबी स्टैंडर्ड लाइब्रेरी में लगभग किसी भी बेसिक ऑब्जेक्ट पर ये हेल्पर मेथड्स प्रदान करती है।
:foo.to_s # => "foo"
10.0.to_i # => 10
"10".to_i # => 10
ये मेथड्स, विशेष रूप से #to_s, रूबी में अधिकांश बेसिक टाइप्स पर लागू होते हैं। जबकि कास्टिंग लगभग हमेशा एक मान लौटाती है, परिणाम वह नहीं हो सकता जिसकी हम उम्मीद करते हैं।
"foo10".to_i # => 0
[1, 2, 3].to_s # => "[1, 2, 3]"
{ :foo => :bar }.to_s # => "{:foo=>:bar}"
{ :foo => :bar }.to_a # => [[:foo, :bar]]
Object.to_s # => "Object"
Object.new.to_s # => "#<Object:0x00007f8e6d053a90>"
#to_s, #to_i, #to_a और #to_h हेल्पर्स को कॉल करने से किसी भी मान को चुने गए टाइप पर बाध्य किया जाता है। वे उस टाइप का प्रतिनिधित्व लौटाते हैं जिसमें इसे कोएर्स किया गया है, भले ही मान का कुछ भी हो जाए।
इम्प्लिसिट कोएर्सन मेथड्स
उन मानों पर टाइप कास्टिंग मेथड्स को कॉल करना जो उस टाइप की तरह कार्य नहीं करते जिसे हम कास्ट कर रहे हैं, त्रुटियों या डेटा हानि का कारण बन सकता है। रूबी इम्प्लिसिट कोएर्सन मेथड्स भी प्रदान करती है जो केवल तभी मान लौटाते हैं जब ऑब्जेक्ट्स उस टाइप की तरह कार्य करते हैं। इस तरह हम सुनिश्चित हो सकते हैं कि मान उस टाइप की तरह कार्य करता है जो हम चाहते हैं। ये इम्प्लिसिट कोएर्सन मेथड्स #to_str, #to_int, #to_ary और #to_hash हैं।
इम्प्लिसिट कोएर्सन लियोनार्ड निमॉय को स्पॉक के अलावा किसी भी भूमिका में कास्ट करने जैसा है। वे काम करेंगे अगर चरित्र स्पॉक के काफी करीब है, लेकिन विफल होंगे अगर वे नहीं हैं। #to_str हेल्पर कोशिश करता है स्ट्रिंग में बदलने की, लेकिन NoMethodError उठाएगा अगर ऑब्जेक्ट मेथड को लागू नहीं करता और इम्प्लिसिटली कोएर्स नहीं किया जा सकता।
10.to_int # => 10
10.0.to_int # => 10
require "bigdecimal"
BigDecimal.new("10.0000123").to_int # => 10
# असफल कोएर्सन्स
"10".to_int # => NoMethodError
"foo10".to_int # => NoMethodError
[1, 2, 3].to_str # => NoMethodError
{ :foo => :bar }.to_str # => NoMethodError
{ :foo => :bar }.to_ary # => NoMethodError
Object.to_str # => NoMethodError
Object.new.to_str # => NoMethodError
हम देख सकते हैं कि रूबी अब थोड़ा अधिक सख्त है कि वह क्या करता है और क्या अनुरोधित टाइप्स में कोएर्स नहीं करता। अगर कोएर्सन संभव नहीं है, तो ऑब्जेक्ट पर #to_* मेथड लागू नहीं होता है और इसे कॉल करने से NoMethodError उठता है।
इम्प्लिसिट कोएर्सन्स का उपयोग करते समय, उदाहरण के लिए #to_str, हम फंक्शन से एक String ऑब्जेक्ट लौटाने के लिए कहते हैं, केवल अगर मूल टाइप भी String की तरह कार्य करता है। इस कारण से, #to_str रूबी स्टैंडर्ड लाइब्रेरी में केवल String पर लागू होता है।
रूबी इम्प्लिसिट कोएर्सन का उपयोग कैसे करती है
कोएर्सन के दौरान हम जो मांग रहे हैं उसमें अधिक सटीक होने के अलावा, इम्प्लिसिट कोएर्सन और किस लिए उपयोगी है? पता चला है कि रूबी स्वयं कई परिदृश्यों में इम्प्लिसिट कोएर्सन्स का उपयोग करती है। उदाहरण के लिए, + के साथ ऑब्जेक्ट्स को संयोजित करते समय।
name = "world!"
"Hello " + name # => "Hello world!"
# #to_str के बिना
class Name
def initialize(name)
@name = name
end
end
"Hello " + Name.new("world!") # => TypeError: no implicit conversion of Name into String
यहां, हम देखते हैं कि रूबी TypeError उठाती है क्योंकि यह Name टाइप से String में इम्प्लिसिट कन्वर्जन नहीं कर सकती।
अगर हम क्लास पर #to_str लागू करते हैं, तो रूबी जानती है कि Name टाइप को कैसे कोएर्स करना है।
# #to_str के साथ
class Name
def to_str
@name
end
end
"Hello " + Name.new("world!") # => "Hello world!"
यही Arrays और #to_ary के लिए काम करता है।
class Options
def initialize
@internal = []
end
def <<(value)
@internal << value
end
end
options = Options.new
options << :foo
[:some_prefix] + options # => TypeError: no implicit conversion of Options into Array
class Options
def to_ary
@internal
end
end
[:some_prefix] + options # => [:some_prefix, :foo]
लेकिन #to_ary अधिक परिदृश्यों में उपयोग किया जाता है। हम इसका उपयोग एक Array को अलग-अलग वेरिएबल्स में डिस्ट्रक्चर करने के लिए कर सकते हैं।
options = Options.new
options << :first
options << :second
options << :third
first, second, third = options
first # => :first
second # => :second
third # => :third
यह ऑब्जेक्ट को ब्लॉक पैरामीटर्स में कन्वर्जन भी करता है।
[options].each do |(first, second)|
first # => :first
second # => :second
end
ऐसे और परिदृश्य हैं जहां इम्प्लिसिट कोएर्सन मेथड्स का उपयोग किया जाता है, जैसे ** के साथ #to_hash। यह parse_options मेथड में पास करने से पहले #to_hash के साथ मान को हैश में कोएर्स करता है।
class Options
def to_hash
# Options Array से हैश बनाएं
Hash[*@internal]
end
end
def parse_options(opts)
opts
end
options = Options.new
options << :key
options << :value
parse_options(**options) # => {:key=>:value}
टाइप्स को लागू करना
रूबी अधिक लचीले कोएर्सन मेथड्स भी प्रदान करती है जब टाइप अज्ञात होता है और हम यह सुनिश्चित करना चाहते हैं कि हमें सही टाइप मिले। हर बेसिक टाइप के लिए एक है (String(...), Integer(...), Float(...), Array(...), Hash(...), आदि)।
String(self) # => "main"
String(self.class) # => "Object"
String(123456) # => "123456"
String(nil) # => ""
Integer(123.999) # => 123
Integer("0x1b") # => 27
Integer(Time.new) # => 1204973019
Integer(nil) # => TypeError: can't convert nil into Integer
String(...) मेथड पहले मान पर #to_str कॉल करने की कोशिश करता है, और जब वह विफल होता है, तो यह इसका #to_s मेथड कॉल करता है। सभी ऑब्जेक्ट्स #to_str मेथड को परिभाषित नहीं करते, इसलिए इम्प्लिसिट कोएर्सन (#to_str) और एक्सप्लिसिट (#to_s) कास्टिंग मेथड्स दोनों के साथ जांच करने से संभावना बढ़ जाती है कि स्ट्रिंग कन्वर्जन काम करेगा और आपको वह मान मिलेगा जो आप चाहते हैं। पहले इम्प्लिसिट कोएर्सन के लिए कॉल करके हमें एक परिणाम मिलने की अधिक संभावना है जिसका मान समान है लेकिन कोएर्स्ड टाइप का है, और "#<Object:0x00007f8e6d053a90>" जैसा कुछ नहीं।
class MyString
def initialize(value)
@value = value
end
def to_str
@value
end
end
s = MyString.new("hello world")
s.to_s # => "#<MyString:0x...>"
s.to_str # => "hello world"
String(s) # => "hello world"
आपको केवल उन ऑब्जेक्ट्स के लिए इम्प्लिसिट कास्टिंग मेथड्स को लागू करना चाहिए जो कोएर्स किए जाने वाले टाइप की तरह कार्य करते हैं, उदाहरण के लिए आपके अपने String क्लास के लिए #to_str।
पहले इम्प्लिसिट कोएर्सन की कोशिश करने के अलावा, String(...) हेल्पर रिटर्न टाइप की भी जांच करता है। #to_str सिर्फ एक मेथड है जो किसी भी टाइप का मान लौटा सकता है, यहां तक कि नॉन-स्ट्रिंग्स भी। यह सुनिश्चित करने के लिए कि हमें अनुरोधित टाइप का मान मिले, String(...) TypeError उठाता है अगर टाइप्स मेल नहीं खाते।
class MyString
def to_str
nil
end
end
s = MyString.new("hello world")
s.to_s # => "#<MyString:0x...>"
s.to_str # => nil
String(s) # => "#<MyString:0x...>"
यहां, हम देख सकते हैं कि रूबी #to_str के परिणाम को नजरअंदाज करती है क्योंकि इसने nil लौटाया, जो String-टाइप का नहीं है। इसके बजाय, यह #to_s परिणाम पर वापस आती है।
अगर #to_s भी nil लौटाता है और इस प्रकार सही टाइप का नहीं है, तो String(...) TypeError उठाएगा।
class MyString
def to_str
nil
end
def to_s
nil
end
end
s = MyString.new("hello world")
s.to_s # => nil
s.to_str # => nil
String(s) # => TypeError: can't convert MyString to String (MyString#to_s gives NilClass)
हालांकि वे टाइप कोएर्सन को लागू करने में अधिक विश्वसनीय हो सकते हैं, ध्यान दें कि कास्टिंग हेल्पर मेथड्स (String(...), Integer(...), आदि) आमतौर पर थोड़े धीमे होते हैं क्योंकि उन्हें दिए गए मान पर अधिक जांच करने की आवश्यकता होती है।
निष्कर्ष
जब आप यह सुनिश्चित करना चाहते हैं कि आप किसी ऑब्जेक्ट के लिए सही टाइप के डेटा से निपट रहे हैं, तो टाइप कोएर्सन एक उपयोगी प्रक्रिया है। इस पोस्ट में, हमने #to_s, #to_i, #to_a और #to_h जैसे एक्सप्लिसिट कास्टिंग हेल्पर्स के अपने ज्ञान को ताज़ा किया। हमने उन उदाहरणों को भी देखा जब #to_str, #to_int, #to_ary और #to_hash जैसे इम्प्लिसिट हेल्पर्स उपयोगी होते हैं और रूबी द्वारा उनका उपयोग कैसे किया जाता है।
हमें उम्मीद है कि आपको यह टाइप कोएर्सन अवलोकन उपयोगी लगा और आपने एक्टर टाइपकास्टिंग सादृश्य को कैसे पाया। हमेशा की तरह, हमें बताएं कि क्या कोई विषय है जिसे आप कवर करना चाहेंगे। यदि आपके कोई प्रश्न या टिप्पणियां हैं, तो @AppSignal पर हमें एक लाइन लिखने में संकोच न करें।