एक चर परिभाषित किया गया है अगर जाँच?


581

मैं कैसे जांच सकता हूं कि क्या रूबी में एक चर परिभाषित किया गया है? वहाँ एक- issetप्रकार की विधि उपलब्ध है?

जवाबों:


791

defined?कीवर्ड ( प्रलेखन ) का उपयोग करें । यह आइटम के प्रकार के साथ एक स्ट्रिंग लौटाएगा, या nilयदि यह मौजूद नहीं है।

>> a = 1
 => 1
>> defined? a
 => "local-variable"
>> defined? b
 => nil
>> defined? nil
 => "nil"
>> defined? String
 => "constant"
>> defined? 1
 => "expression"

जैसा कि स्केले ने टिप्पणी की: "यह ध्यान देने योग्य है कि जिस चर को शून्य पर सेट किया गया है, वह आरंभिक है।"

>> n = nil  
>> defined? n
 => "local-variable"

92
यह ध्यान देने योग्य है कि जो चर सेट किया गया nil है वह आरंभिक है।
स्केले

7
यदि आप एक चर सेट करना चाहते हैं यदि यह मौजूद नहीं है और यदि यह करता है तो इसे अकेला छोड़ दें, @ danmayer का उत्तर ( ||=ऑपरेटर को शामिल करना ) देखें।
जूनियरको

2
यहाँ एक और विचित्रता है जो मैं कर सकता हूँ .. अगर आप एक वैरिएबल को इफ-ब्लॉक में परिभाषित करते हैं जिसके लिए स्थिति कभी पूरी नहीं होती है, तब defined?भी उस ब्लॉक के भीतर परिभाषित एक वैरिएबल के लिए सही रहता है!
एल्सरुडो

1
क्या ऐसी कोई विधि है defined?जो रिटर्न बूलियन है?
stevec

सही / गलत लौटने के लिए, !!defined?(object_name)
stevec

91

यह उपयोगी है यदि आप कुछ भी नहीं करना चाहते हैं अगर यह मौजूद नहीं है, लेकिन अगर यह मौजूद नहीं है तो इसे बनाएं।

def get_var
  @var ||= SomeClass.new()
end

यह केवल एक बार नया उदाहरण बनाता है। इसके बाद यह सिर्फ var को वापस करता रहता है।


9
यह बहुत ही मुहावरेदार रूबी भी है और बहुत विशिष्ट है, वैसे।
जूनियरको

38
बस ||=बूलियन मूल्यों के साथ उपयोग न करें , ऐसा न हो कि आप भ्रम के दर्द को महसूस करते हैं।
एंड्रयू मार्शल

6
@AndrewMarshall ने क्या कहा, इसके साथ ही इस मुहावरे से भी बचें, जो nilतब तक वापस आ सकता है जब तक कि आप वास्तव में हर बार जब इसे वापस बुलाते हैं तो अभिव्यक्ति का मूल्यांकन नहीं करना चाहतेnil
nzifnab

1
यदि आप बूलियन्स के साथ काम कर रहे हैं , और चाहते हैं कि डिफ़ॉल्ट मूल्य सही हो अगर चर स्पष्ट रूप से गलत पर सेट नहीं किया गया था, तो आप इस निर्माण का उपयोग कर सकते हैं: var = (var or var.nil?)
टोनी जीतो

1
@ArnaudMeuret वास्तव में नहीं। - जबकि यह समान नहीं लग सकता है, यह उस सवाल पर जवाब पढ़ने के लायक है।
फंड मोनिका का मुकदमा

70

उपरोक्त कथन का सही सिंटैक्स है:

if (defined?(var)).nil? # will now return true or false
 print "var is not defined\n".color(:red)
else
 print "var is defined\n".color(:green)
end

प्रतिस्थापन ( var) अपने चर के साथ। यह वाक्यविन्यास यदि विवरण में मूल्यांकन के लिए एक सही / गलत मान लौटाएगा।


11
यह आवश्यक नहीं है क्योंकि जब परीक्षण में इस्तेमाल किया जाता है तो झूठे का मूल्यांकन करता है
जेरोम

क्यों नहीं defined?(var) == nil?
Vol7ron

@ vol7ron - यह पूरी तरह से वैध सिंटैक्स है। .nil?जैसा कि वे कहते हैं, कॉल का उपयोग करना अधिक मुहावरेदार है। किसी ऑब्जेक्ट nilको तुलना ऑपरेटर से उपयोग करने की तुलना में यह अधिक "ऑब्जेक्ट-ओरिएंटेड" है । न तो पढ़ना मुश्किल है, इसलिए जो भी आपको अधिक उत्पाद जहाज करने में मदद करता है।
जुआनपाको

आप किस कथन का उल्लेख कर रहे हैं? किसी और चीज़ के लिए एक उत्तर का उपयोग न करें।
अरनॉड म्यूरेट

18

defined?(your_var)काम करेगा। आप जो कर रहे हैं उसके आधार पर आप भी कुछ ऐसा कर सकते हैंyour_var.nil?


+1 के लिए your_var.nil?क्योंकि यह असत्य का सच है और पढ़ने और लिखने के लिए बहुत अच्छा है defined? var। इसके लिए धन्यवाद।
काकुबई

28
your_var.nil?परिणाम में त्रुटि होगी: undefined local variable or method your_varजब पहले परिभाषित नहीं ...
Gobol

16

"If" के बजाय "if" का प्रयास करें

a = "apple"
# Note that b is not declared
c = nil

unless defined? a
    puts "a is not defined"
end

unless defined? b
    puts "b is not defined"
end

unless defined? c
    puts "c is not defined"
end

यह उत्तर क्या जोड़ता है जो अन्य उत्तरों द्वारा नहीं कहा गया है?
एंड्रयू ग्रिम

2
यह बहुत अच्छी तरह से एक और उपयोगी तरीके से सवाल का जवाब देता है, है ना?
देखो

2
गहरे लाल रंग का स्टाइल गाइड कहते हैं, "जब तक फ़ेवर से अधिक है, तो नकारात्मक स्थितियों के लिए" github.com/bbatsov/ruby-style-guide
ChrisPhoenix


8

यहाँ कुछ कोड है, कुछ भी रॉकेट साइंस नहीं है लेकिन यह काफी अच्छी तरह से काम करता है

require 'rubygems'
require 'rainbow'
if defined?(var).nil?  # .nil? is optional but might make for clearer intent.
 print "var is not defined\n".color(:red)
else
 print "car is defined\n".color(:green)
end

स्पष्ट रूप से, रंग कोड आवश्यक नहीं है, बस इस खिलौना उदाहरण में एक अच्छा दृश्य है।


संभवत: nil?वैकल्पिक है।
जेम्स

8

पुन: एक सामान्य रूबी पैटर्न

यह प्रमुख उत्तर है: defined?विधि। ऊपर दिया गया स्वीकृत उत्तर इसे पूरी तरह दिखाता है।

लेकिन एक शार्क है, जो लहरों के नीचे दुबकी हुई है ...

इस प्रकार के सामान्य रूबी पैटर्न पर विचार करें:

 def method1
    @x ||= method2
 end

 def method2
    nil
 end

method2हमेशा लौटता है nil। पहली बार जब आप कॉल करते हैं method1, तो @xचर सेट नहीं किया जाता है - इसलिए method2चलाया जाएगा। और method2सेट हो जाएगा @xकरने के लिए nil। यह ठीक है, और सभी अच्छी तरह से और अच्छा है। लेकिन दूसरी बार फोन करने पर क्या होता हैmethod1 ?

याद रखें @ x पहले ही शून्य पर सेट हो चुका है। But method2अभी भी फिर से चलाया जाएगा !! यदि Method2 एक महंगा उपक्रम है, तो यह कुछ ऐसा नहीं है जो आप चाहते हैं।

defined?विधि को बचाव में आने दें - इस समाधान के साथ, उस विशेष मामले को संभाला जाता है - निम्नलिखित का उपयोग करें:

  def method1
    return @x if defined? @x
    @x = method2
  end

शैतान विवरण में है: लेकिन आप उस गुप्त शार्क को defined?विधि से निकाल सकते हैं ।


आप पूरी तरह से सही हैं, उस विशिष्ट चेतावनी को उजागर करने के लिए धन्यवाद
कुलगर

5

तुम कोशिश कर सकते हो:

unless defined?(var)
  #ruby code goes here
end
=> true

क्योंकि यह एक बूलियन देता है।


SyntaxError: compile error (irb):2: syntax error, unexpected $end, expecting kEND
एंड्रयू ग्रिम

एक unlessबयान का उपयोग करने के लिए अत्यधिक जटिल लगता है
जोहान्स

5

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

लेकिन अगर आपको पूरी तरह से बूलियन की जरूरत है। उपयोग !! (बैंग बैंग) या "झूठे झूठे सच को उजागर करता है"।

 irb
>> a = nil
=> nil
>> defined?(a)
=> "local-variable"
>> defined?(b)
=> nil
>> !!defined?(a)
=> true
>> !!defined?(b)
=> false

क्यों यह आमतौर पर भुगतान करने के लिए मजबूर नहीं करता है:

>> (!!defined?(a) ? "var is defined".colorize(:green) : "var is not defined".colorize(:red)) == (defined?(a) ? "var is defined".colorize(:green) : "var is not defined".colorize(:red))
=> true

यहां एक उदाहरण है जहां यह मायने रखता है क्योंकि यह अपने स्ट्रिंग प्रतिनिधित्व के लिए बूलियन मूल्य के अंतर्निहित जोर पर निर्भर करता है।

>> puts "var is defined? #{!!defined?(a)} vs #{defined?(a)}"
var is defined? true vs local-variable
=> nil

3

यह उल्लेख किया जाना चाहिए कि definedहैश में विशिष्ट क्षेत्र निर्धारित होने पर जाँच करने के लिए उपयोग करना अप्रत्याशित हो सकता है:

var = {}
if defined? var['unknown']
  puts 'this is unexpected'
end
# will output "this is unexpected"

यहां सिंटैक्स सही है, लेकिन defined? var['unknown']स्ट्रिंग का मूल्यांकन किया जाएगा "method", इसलिए ifब्लॉक निष्पादित किया जाएगा

संपादित करें: यदि हैश में कोई कुंजी मौजूद है, तो जाँच के लिए सही अंकन:

if var.key?('unknown')

2

कृपया "परिभाषित" और "असाइन" के बीच अंतर पर ध्यान दें।

$ ruby -e 'def f; if 1>2; x=99; end;p x, defined? x; end;f'
nil
"local-variable"

एक्स को परिभाषित किया गया है, भले ही यह कभी नहीं सौंपा गया हो!


यह कुछ ऐसा है जिसे मैंने अभी-अभी देखा है। मैं उम्मीद कर रहा था NameError Exception: undefined local variable or method, और उलझन में था जब चर का एकमात्र असाइनमेंट / उल्लेख एक अगर ब्लॉक में था जो हिट नहीं हो रहा था।
पॉल पेटेंगेंग

0

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

puts "Is array1 defined and what type is it? #{defined?(@array1)}"

यदि आप इसे परिभाषित करते हैं तो सिस्टम आपको प्रकार बताएगा। यदि इसे परिभाषित नहीं किया जाता है, तो यह केवल एक चेतावनी कह कर वापस कर देगा जिसमें चर को आरंभीकृत नहीं किया गया है।

उम्मीद है की यह मदद करेगा! :)


0

defined?बहुत अच्छा है, लेकिन अगर आप रेल के माहौल में हैं, तो आप भी उपयोग कर सकते हैं try, खासकर उन मामलों में जहां आप एक गतिशील चर नाम की जांच करना चाहते हैं:

foo = 1
my_foo = "foo"
my_bar = "bar"
try(:foo)        # => 1
try(:bar)        # => nil
try(my_foo)      # => 1
try(my_bar)      # => nil
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.