class MyClass
def mymethod
MYCONSTANT = "blah"
end
end
मुझे त्रुटि देता है:
SyntaxError: डायनेमिक निरंतर असाइनमेंट त्रुटि
इसे गतिशील स्थिरांक क्यों माना जाता है? मैं इसे एक स्ट्रिंग सौंप रहा हूँ।
class MyClass
def mymethod
MYCONSTANT = "blah"
end
end
मुझे त्रुटि देता है:
SyntaxError: डायनेमिक निरंतर असाइनमेंट त्रुटि
इसे गतिशील स्थिरांक क्यों माना जाता है? मैं इसे एक स्ट्रिंग सौंप रहा हूँ।
जवाबों:
आपकी समस्या यह है कि हर बार जब आप विधि को चलाते हैं तो आप स्थिरांक को एक नया मान दे रहे हैं। यह अनुमति नहीं है, क्योंकि यह निरंतर गैर-स्थिर बनाता है; भले ही स्ट्रिंग की सामग्री समान हो (फिलहाल, किसी भी तरह), वास्तविक स्ट्रिंग ऑब्जेक्ट अपने आप में अलग-अलग होता है, जब विधि को बुलाया जाता है। उदाहरण के लिए:
def foo
p "bar".object_id
end
foo #=> 15779172
foo #=> 15779112
शायद अगर आपने अपने उपयोग के मामले को समझाया — तो आप एक विधि में स्थिरांक का मूल्य क्यों बदलना चाहते हैं - हम आपको बेहतर क्रियान्वयन में मदद कर सकते हैं।
शायद आपके पास कक्षा पर एक उदाहरण चर होगा?
class MyClass
class << self
attr_accessor :my_constant
end
def my_method
self.class.my_constant = "blah"
end
end
p MyClass.my_constant #=> nil
MyClass.new.my_method
p MyClass.my_constant #=> "blah"
यदि आप वास्तव में किसी विधि में किसी स्थिरांक का मान बदलना चाहते हैं, और आपका स्थिरांक एक स्ट्रिंग या एक ऐरे है, तो आप #replaceवास्तव में वस्तु को बदले बिना वस्तु को नए मूल्य पर ले जाने के लिए विधि को 'धोखा' दे सकते हैं और उपयोग कर सकते हैं :
class MyClass
BAR = "blah"
def cheat(new_bar)
BAR.replace new_bar
end
end
p MyClass::BAR #=> "blah"
MyClass.new.cheat "whee"
p MyClass::BAR #=> "whee"
def initialize(db,user,password) DB=Sequel.connect("postgres://#{user}:#{password}@localhost/#{db}") end। यह उन मामलों में से एक है जहां रूबी के पास कोई सरल तरीका नहीं है।
@variable) चाहते हैं, स्थिर नहीं। अन्यथा आप DBहर बार जब आप उस वर्ग के एक नए उदाहरण को फिर से असाइन करेंगे, तो आप फिर से असाइन हो जाएंगे ।
Sequel.connectडीबी के साथ एक निरंतरता का परिणाम सौंपना है । वास्तव में, प्रलेखन स्पष्ट रूप से कहता है कि यह सिर्फ एक सिफारिश है। यह मेरे लिए एक बाहरी बाधा की तरह नहीं है।
क्योंकि रूबी में स्थिरांक को बदलने का मतलब नहीं है, रूबी आपको कोड के कुछ हिस्सों में उन्हें असाइन करने से हतोत्साहित करता है जो कि एक से अधिक बार निष्पादित हो सकते हैं, जैसे कि अंदर के तरीके।
सामान्य परिस्थितियों में, आपको कक्षा के अंदर निरंतर को परिभाषित करना चाहिए:
class MyClass
MY_CONSTANT = "foo"
end
MyClass::MY_CONSTANT #=> "foo"
यदि किसी कारण से, हालांकि आपको वास्तव में एक विधि के अंदर एक स्थिरांक को परिभाषित करने की आवश्यकता है (शायद कुछ प्रकार के मेटाप्रोग्रामिंग के लिए), तो आप निम्न कार्य कर सकते हैं const_set:
class MyClass
def my_method
self.class.const_set(:MY_CONSTANT, "foo")
end
end
MyClass::MY_CONSTANT
#=> NameError: uninitialized constant MyClass::MY_CONSTANT
MyClass.new.my_method
MyClass::MY_CONSTANT #=> "foo"
फिर भी, const_setकुछ ऐसा नहीं है जिसे आपको वास्तव में सामान्य परिस्थितियों में सहारा लेना चाहिए। यदि आप सुनिश्चित नहीं हैं कि आप वास्तव में इस तरह से स्थिरांक देना चाहते हैं, तो आप निम्नलिखित विकल्पों में से एक पर विचार करना चाह सकते हैं:
कक्षा चर कई मायनों में स्थिरांक की तरह व्यवहार करते हैं। वे एक वर्ग पर गुण हैं, और वे उस वर्ग के उपवर्गों में सुलभ हैं जिन्हें वे परिभाषित किया गया है।
अंतर यह है कि वर्ग चर को परिवर्तनीय माना जाता है, और इसलिए इसे बिना किसी समस्या के अंदर के तरीकों को सौंपा जा सकता है।
class MyClass
def self.my_class_variable
@@my_class_variable
end
def my_method
@@my_class_variable = "foo"
end
end
class SubClass < MyClass
end
MyClass.my_class_variable
#=> NameError: uninitialized class variable @@my_class_variable in MyClass
SubClass.my_class_variable
#=> NameError: uninitialized class variable @@my_class_variable in MyClass
MyClass.new.my_method
MyClass.my_class_variable #=> "foo"
SubClass.my_class_variable #=> "foo"
वर्ग विशेषताएँ "एक वर्ग पर उदाहरण चर" का एक प्रकार हैं। वे वर्ग चर की तरह थोड़ा व्यवहार करते हैं, सिवाय इसके कि उनके मूल्यों को उपवर्गों के साथ साझा नहीं किया जाता है।
class MyClass
class << self
attr_accessor :my_class_attribute
end
def my_method
self.class.my_class_attribute = "blah"
end
end
class SubClass < MyClass
end
MyClass.my_class_attribute #=> nil
SubClass.my_class_attribute #=> nil
MyClass.new.my_method
MyClass.my_class_attribute #=> "blah"
SubClass.my_class_attribute #=> nil
SubClass.new.my_method
SubClass.my_class_attribute #=> "blah"
और सिर्फ पूर्णता के लिए मुझे शायद उल्लेख करना चाहिए: यदि आपको एक मूल्य निर्दिष्ट करने की आवश्यकता है जो केवल आपकी कक्षा के तुरंत बाद निर्धारित की जा सकती है, तो एक अच्छा मौका है जो आप वास्तव में एक सादे पुराने उदाहरण चर के लिए देख सकते हैं।
class MyClass
attr_accessor :instance_variable
def my_method
@instance_variable = "blah"
end
end
my_object = MyClass.new
my_object.instance_variable #=> nil
my_object.my_method
my_object.instance_variable #=> "blah"
MyClass.new.instance_variable #=> nil
रूबी में, कोई भी चर जिसका नाम एक बड़े अक्षर से शुरू होता है, एक स्थिरांक है और आप इसे केवल एक बार असाइन कर सकते हैं। इनमें से कोई एक विकल्प चुनें:
class MyClass
MYCONSTANT = "blah"
def mymethod
MYCONSTANT
end
end
class MyClass
def mymethod
my_constant = "blah"
end
end
माणिक में स्थिरांक को विधियों के अंदर परिभाषित नहीं किया जा सकता है। उदाहरण के लिए, इस पृष्ठ के नीचे स्थित नोट्स देखें
आप बड़े अक्षरों के साथ एक चर का नाम नहीं दे सकते हैं या रूबी एक स्थिर मान लेगा और यह चाहेगा कि यह मूल्य स्थिर बना रहे, जिस स्थिति में यह मूल्य बदल रहा है वह एक "गतिशील निरंतर असाइनमेंट त्रुटि" होगी। कम मामले के साथ ठीक होना चाहिए
class MyClass
def mymethod
myconstant = "blah"
end
end
रूबी को यह पसंद नहीं है कि आप किसी विधि के अंदर निरंतर असाइन कर रहे हैं क्योंकि यह पुन: असाइनमेंट को जोखिम में डालता है। मेरे सामने कई एसओ जवाब एक विधि के बाहर इसे असाइन करने का विकल्प देते हैं - लेकिन कक्षा में, जो इसे असाइन करने के लिए एक बेहतर जगह है।
डोरियन और फ्रॉग्ज के लिए कई धन्यवाद मुझे सरणी (और हैश) विधि #replace के बारे में याद दिलाने के लिए, जो "किसी सरणी या हैश की सामग्री को प्रतिस्थापित कर सकता है।"
यह धारणा कि एक CONSTANT का मूल्य बदला जा सकता है, लेकिन एक कष्टप्रद चेतावनी के साथ, रूबी के कुछ वैचारिक गलत कदमों में से एक है - ये या तो पूरी तरह से अपरिवर्तनीय होना चाहिए, या स्थिर विचार को पूरी तरह से डुबो देना चाहिए। एक कोडर के दृष्टिकोण से, एक निरंतर घोषणात्मक और जानबूझकर है, अन्य के लिए एक संकेत है कि "यह मूल्य वास्तव में अपरिवर्तनीय है जो केवल घोषित या असाइन किया गया है।"
लेकिन कभी-कभी "स्पष्ट घोषणा" वास्तव में अन्य, भविष्य के उपयोगी अवसरों को प्रभावित करती है। उदाहरण के लिए...
वहाँ रहे हैं उदाहरण के लिए, एक आरईपीएल की तरह शीघ्र लूप से फिर से लोड हो रहा है ARGV, तो के माध्यम से अधिक (बाद) OptionParser.parse ARGV का पुनर्प्रसारण: वैधानिक उपयोग के मामले में जहां एक "निरंतर के" मूल्य वास्तव में परिवर्तित करने की आवश्यकता हो सकता है! कॉल - वॉइला! "कमांड लाइन आर्ग्स" एक पूरी नई गतिशील उपयोगिता देता है।
व्यावहारिक समस्या या तो अनुमान लगाने योग्य धारणा के साथ है कि "ARGV एक स्थिर होना चाहिए", या ऑप्टपर्स की अपनी इनिशियलाइज़ विधि में, जो ARGV के असाइनमेंट को बाद के प्रोसेसिंग के लिए var @default_arv पर हार्ड कोड को कोड करता है - वह सरणी (ARGV) वास्तव में एक पैरामीटर होना चाहिए, जहां पुन: पार्स और फिर से उपयोग को प्रोत्साहित करना, जहां उपयुक्त हो। एक उचित डिफ़ॉल्ट (कहते हैं, ARGV) के साथ उचित पैरामीटर, कभी भी "स्थिर" ARGV को बदलने की आवश्यकता से बचता है। बस कुछ 2 some-विचारों के गुण ...