रूबी में, अगर विधि "फू = ()" को परिभाषित किया गया है तो मैं कैसे जांच करूं?


81

रूबी में, मैं एक विधि को परिभाषित कर सकता हूं foo = (बार):

irb(main):001:0> def foo=(bar)
irb(main):002:1>   p "foo=#{bar}"
irb(main):003:1> end
=> nil

अब मैं जाँच करना चाहता हूँ कि क्या यह परिभाषित किया गया है,

irb(main):004:0> defined?(foo=)
SyntaxError: compile error
(irb):4: syntax error, unexpected ')'
 from (irb):4
 from :0

यहाँ उपयोग करने के लिए उचित वाक्यविन्यास क्या है? मेरा मानना ​​है कि "फू =" से बचने का एक तरीका होना चाहिए ताकि इसे परिभाषित किया जाए और परिभाषित रूप से सही तरीके से पारित किया जाए? ऑपरेटर।

जवाबों:


132

समस्या यह है कि इस foo=पद्धति को असाइनमेंट में उपयोग करने के लिए डिज़ाइन किया गया है। आप defined?निम्नलिखित तरीकों से उपयोग कर सकते हैं कि क्या हो रहा है:

defined? self.foo=()
#=> nil
defined? self.foo = "bar"
#=> nil

def foo=(bar)
end

defined? self.foo=()
#=> "assignment"
defined? self.foo = "bar"
#=> "assignment"

इसकी तुलना करें:

def foo
end

defined? foo
#=> "method"

foo=यह निर्धारित करने के लिए कि क्या विधि परिभाषित है, आपको respond_to?इसके बजाय उपयोग करना चाहिए :

respond_to? :foo=
#=> false

def foo=(bar)
end

respond_to? :foo=
#=> true

धन्यवाद! इससे मेरी समस्या हल हो गई। मैं अभी भी यह जानने के लिए उत्सुक हूं कि क्या फू से बचने का कोई तरीका है = जैसे कि इसे परिभाषित किया जा सकता है? लेकिन कम से कम अब मैं आगे बढ़ सकता हूं।
एलेक्स बोविवर्ट

1
यहां समस्या यह है कि foo=हमेशा असाइनमेंट में उपयोग किया जाता है, इसलिए "assignment"यदि आप परीक्षण करते हैं तो रूबी वापस आ जाएगी defined? foo()(अपडेट किया गया उत्तर देखें)।
मॉल्फ

43

आप देख सकते हैं कि क्या विधि का उपयोग करके कोई विधि मौजूद है respond_to?, और आप इसे एक प्रतीक पास करते हैं, उदाहरण के bar.respond_to?(:foo=)लिए यह देखने के लिए कि क्या वस्तु barमें कोई विधि है foo=। यदि आप जानना चाहते हैं कि क्या किसी वर्ग के उदाहरण एक ऐसी विधि का जवाब देते हैं जिसका आप method_defined?कक्षा (या मॉड्यूल) पर उपयोग कर सकते हैं , उदाहरण के लिए Foo.method_defined?(:bar=)

defined?एक विधि नहीं है, लेकिन एक ऑपरेटर जो ऑपरेंड का विवरण देता है (या शून्य यदि यह परिभाषित नहीं किया गया है, यही कारण है कि इसका उपयोग यदि एक बयान में किया जा सकता है)। ऑपरेंड कोई भी अभिव्यक्ति हो सकता है, अर्थात एक स्थिर, एक चर, एक असाइनमेंट, एक विधि, एक विधि कॉल, आदि। यही कारण है कि जब आप करते हैं तो यह काम नहीं करता defined?(foo=)है क्योंकि कोष्ठक के कारण, उन्हें छोड़ दें और इसे अधिक काम करना चाहिए या उम्मीद के मुताबिक कम। यह कहा जा रहा है, defined?एक बहुत अजीब ऑपरेटर है, और कोई भी इसका उपयोग तरीकों के अस्तित्व के लिए परीक्षण करने के लिए नहीं करता है।


यह response_to है ?, प्रतिक्रियाएँ_to नहीं?
0x4a6f4672

3
आह, रूबी कोर पुस्तकालय की वर्तनी ... respond_to?, start_with?, end_with?
थियो

3
stackoverflow.com/questions/5280556/… नामकरण टीएल के पीछे चुनाव का एक अच्छा विवरण है; DRyou.knock if you.respond_to?(:knock)
drewish
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.