वहाँ एक रूबी है, या रूबी- ism not_nil के लिए है? नील के विपरीत? तरीका?


87

मैं रूबी में अनुभवी नहीं हूं, इसलिए मेरा कोड "बदसूरत" लगता है और मुहावरेदार नहीं:

def logged_in?
  !user.nil?
end

मुझे कुछ पसंद है

def logged_in?
  user.not_nil?
end

लेकिन ऐसी विधि नहीं खोज सकते जो विरोध करे nil?

जवाबों:


51

जब आप ActiveSupport का उपयोग कर रहे हों, तो वहाँ केवल गैर-शून्य के लिए जाँच करने के लिए user.present? http://api.rubyonrails.org/classes/Object.html#method-i-face%3F है , क्यों नहीं उपयोग करें

def logged_in?
  user # or !!user if you really want boolean's
end

48
खबरदार: present?एक गैर-रिक्त स्ट्रिंग की आवश्यकता होती है। ! "".nil?सच्चा लौटाता है, लेकिन "".present?झूठा देता है।
लाम्बनसी

9
खबरदार 2: मैं यह भी ध्यान रखूँगा कि उपयोगकर्ता शून्य और उपयोगकर्ता के झूठे होने के बीच अंतर नहीं करता है! दोहरे धमाके का उपयोग उन दोनों को भ्रमित करता है। इसलिए यदि आप वास्तव में यह निर्धारित करना चाहते हैं कि कोई वस्तु शून्य नहीं है (मतलब, यह: सच, गलत, 0, "", शून्य के अलावा कुछ भी), तो आपको 'बदसूरत' दृष्टिकोण का उपयोग करने की आवश्यकता है जो कि बर्क को पसंद नहीं है या मंकीचैट कि @ टैम्पस नीचे प्रस्तावित करता है । बेशक इस मामले में जहां शून्य की आवश्यकता नहीं है (पटरियों में एक उपयोगकर्ता), सामो द्वारा लिया गया दृष्टिकोण कम से कम बदसूरत, इमो है।
इसी तरह

12
false.present? == false !false.nil? == true
डूडो

3
यह उत्तर पूछे गए प्रश्न का उत्तर नहीं देता है। यह इस विशेष कार्यान्वयन समस्या का जवाब है।
एक्कस्टीन

3
यह उत्तर सही नहीं है। false.nil? गलत है, जबकि गलत है। यह भी गलत है!
माइक

49

आप बूलियन से अत्यधिक चिंतित लगते हैं।

def logged_in?
  user
end

यदि उपयोगकर्ता शून्य है, तो log_in? एक "गलत" मान लौटाएगा। अन्यथा, यह एक वस्तु लौटाएगा। रूबी में हमें सच या झूठ की वापसी की आवश्यकता नहीं है, क्योंकि हमारे पास जावास्क्रिप्ट में "सच्चाई" और "गलत" मान हैं।

अपडेट करें

यदि आप रेल का उपयोग कर रहे हैं, तो आप present?विधि का उपयोग करके इसे अधिक अच्छी तरह से पढ़ सकते हैं :

def logged_in?
  user.present?
end

1
एक के साथ समाप्त होने वाली विधि के साथ उम्मीद ?यह है कि यह एक बूलियन लौटाता है। !!valueएक बूलियन के लिए कुछ भी परिवर्तित करने का क्लासिक तरीका है। बिल्कुल वैसा ही नहीं, लेकिन इस मामले Object#present?में आरओआर भी अच्छा है।
20

यह वास्तव में पथ के साथ रूबी 2.4 में टूट जाता है! [४३] (pry) # <ReactOnRails :: AssetsPrecompile>: ०> संपत्ति_पथ_ब्लैंक? सच [४४] (pry) # <ReactOnRails :: AssetsPrecompile>: ०> संपत्तियां_पठ.तो_स ’’ / var / फ़ोल्डर / आरपी / _k99k0pn0rsb4d3dm9l3dnjh0000gn/ टी / d20170603-96466-zk7-7x7/77 >: 0> assets_path.pret? झूठी [४६] (pry) # <ReactOnRails :: AssetsPrecompile>: ०> आस्तियों_पथ_निल? झूठी
justingordon

25

present?अपने प्रश्न के उत्तर के रूप में प्रस्तुत अन्य उत्तरों से सावधान रहें ।

present?blank?रेल के विपरीत है ।

present?जाँच करता है कि क्या सार्थक मूल्य है। ये चीजें एक present?चेक को विफल कर सकती हैं :

"".present? # false
"    ".present? # false
[].present? # false
false.present? # false
YourActiveRecordModel.where("false = true").present? # false

जबकि एक !nil?चेक देता है:

!"".nil? # true
!"    ".nil? # true
![].nil? # true
!false.nil? # true
!YourActiveRecordModel.where("false = true").nil? # true

nil?जाँचता है कि क्या वास्तव में कोई वस्तु है nil। और कुछ: एक खाली स्ट्रिंग, 0, false, जो कुछ भी, नहीं है nil

present?बहुत उपयोगी है, लेकिन निश्चित रूप से इसके विपरीत नहीं है nil?। दोनों को भ्रमित करने से अप्रत्याशित त्रुटियां हो सकती हैं।

आपके उपयोग के मामले present?में काम करेगा, लेकिन अंतर के बारे में पता होना हमेशा बुद्धिमान होता है।


स्वीकृत उत्तर में शामिल होना चाहिए। false.blank?के रूप में ही नहीं हैfalse.nil?
Yason

present?आपके डेटाबेस को क्वेरी करेगा, nil?इसके साथ सावधान नहीं होगा
टोनी

17

शायद यह एक दृष्टिकोण हो सकता है:

class Object
  def not_nil?
    !nil?
  end
end

अच्छा विचार। मैं इससे बनाता हूं कि कोई not_nil नहीं है? रूबी में। लेकिन यह !self.nil?तब नहीं होना चाहिए !nil?, या selfनिहित है?
Berkes

3
आप स्वयं की जरूरत नहीं है। यह निहित होगा।
जियो

उदाहरण विधियों (या एक्सेसर्स, जो वास्तव में सिर्फ तरीके हैं) से पढ़ते समय स्वयं निहित है। मान सेट करते समय, रूबी से पहले एक वैरिएबल लोकल बनाया जाएगा, उसी नाम की सेटर विधि के लिए क्लास के उदाहरण की जाँच करता है। सामान्य नियम: यदि आपके पास xxx नामक एक attr_accessor है, तो "self.xxx = 3" (मान सेट करना) या "temp = xxx" (मान पढ़ना) का उपयोग करें। "Xxx = 3" का उपयोग करने से एक्सेसर अपडेट नहीं होगा, बस विधि क्षेत्र में एक नया चर बनाएं।
एक फादर डार्कली

4

आप बस निम्नलिखित का उपयोग कर सकते हैं:

if object
  p "object exists"
else
  p "object does not exist"
end

यह न केवल नील बल्कि झूठे आदि के लिए भी काम करता है, इसलिए आपको यह देखने के लिए परीक्षण करना चाहिए कि क्या यह आपके usecase में काम करता है।


4

क्या मैं !विधि से परिणाम पर रूबी-एस्क विधि की पेशकश कर सकता हूं nil?

def logged_in?
  user.nil?.!
end

इतना गूढ़ कि रूबीमाइन आईडीई इसे एक त्रुटि के रूप में चिह्नित करेगा। ;-)


2

मैं एक वस्तु विधि की तलाश में इस सवाल पर पहुंचा, ताकि मैं ब्लॉक के बजाय Symbol#to_procशॉर्टहैंड का उपयोग कर सकूं ; मुझे arr.find(&:not_nil?)इससे कहीं अधिक पठनीय लगता है arr.find { |e| !e.nil? }

मुझे जो विधि मिली है Object#itself। मेरे उपयोग में, मैं कुंजी के लिए एक हैश में मान ढूंढना चाहता था name, जहां कुछ मामलों में कुंजी को गलती से पूंजीकृत किया गया था Name। वह वन-लाइनर इस प्रकार है:

# Extract values for several possible keys 
#   and find the first non-nil one
["Name", "name"].map { |k| my_hash[k] }.find(&:itself)

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


वह किस तरह से अलग है my_hash.values_at("Name", "name").find?
Berkes

बिलकुल ऐसा ही है। मेरे पास मेरे मूल में कुछ और तर्क थे mapजिन्हें मैंने इस उदाहरण में सरलता के लिए हटा दिया था, इसलिए जैसा कि यहां लिखा गया है यह इसके साथ विनिमेय है values_at। महत्वपूर्ण हिस्सा वह है जो पास हो जाता है find
इयान
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.