2012-01-23 13 views
9

मैं बस रूबी में आ रहा हूं और जावा और सी/सी ++ पर्यावरण से आया हूं।क्या अंडरस्कोर से शुरू होने वाले स्थानीय चर वाले अच्छे अभ्यास हैं?

रुबी में पहली छोटी परियोजना को कोड करते समय, मैंने किसी भी तरह से सभी स्थानीय चर अंडरस्कोर से शुरू करने के लिए उपयोग किया। मुझे लगता है कि इसके लिए मेरा मुख्य प्रेरणा विधि कॉल से बेहतर पठनीयता और भेद था।

सिद्धांत रूप में केवल तीन प्रकार के चर होते हैं ($global, @instance और local), चर के बहुमत अंडरस्कोर से शुरू होते हैं। मुझे सच में यकीन नहीं है, चाहे यह अच्छा या बुरा हो। इसके अलावा, कई अन्य भाषाओं में, अंडरस्कोर को किसी अन्य चरित्र में प्रतिस्थापित किया जाएगा।

वहाँ किसी भी तरह सामान्य केमलकेस और/या अंडरस्कोर अलग के बगल में एक सबसे अच्छा अभ्यास के विषय में चर नामकरण है? पेशेवर "rubyists" की आदतें क्या हैं? क्या मैंने कुछ सामान्य रूबी सम्मेलनों को नजरअंदाज कर दिया है, जब मैंने अग्रणी अंडरस्कोर चुना था?


संपादित
सभी उत्तर और सुझाव के लिए धन्यवाद। इसने मेरी बहुत मदद की।

  • विधि तर्क:


    नीचे
    जवाब और टिप्पणियाँ की कमी सारांश (लघु-ऑन-बार आगंतुक के लिए)

    अग्रणी अंडरस्कोर से जाना def my_method(_my_arg)

  • ब्लॉक तर्क: उदाहरण के लिए my_array.each { |_x| puts _x}

अन्य अंडरस्कोर के बिना अन्य सभी स्थानीय चर, जैसे प्रोग्रामर आ रहे हैं उदा। चर के इरादे से व्यवहार के बारे में JavaScript might get confused

चर नाम और विधि कॉल के बीच दृश्य जुदाई के लिए

, अपने आप को मजबूर कर सभी विधि कॉल के साथ "(" कोष्ठक ")" का उपयोग करने के लिए काफी पठनीयता बढ़ सकता है।

+1

अन्य भाषाएं वास्तव में चिंता का विषय नहीं हैं, क्योंकि प्रत्येक भाषा में अलग-अलग कोडिंग शैलियों हैं। मैं कभी-कभी ब्लॉक पैरामीटर में अग्रणी अंडरस्कोर के साथ चर का उपयोग करता हूं, यानी '{| _a, _b | ...} 'जब मैं उन्हें बाहर खड़ा करना चाहता हूं, या यह कोड को और अधिक पठनीय बनाता है। पठनीयता समय के साथ रखरखाव के लिए अनुवाद करती है, इसलिए अपनी आंखों में क्या बहती है और बाहर निकलती है और सबसे आसान है। –

+0

@theTinman: ब्लॉक तर्कों के साथ अंडरस्कोर भी एक उचित तरीका प्रतीत होता है। उसके लिए धन्यवाद। –

+0

@ टोरबोजोर्न संक्षिप्त सारांश के लिए धन्यवाद, बहुत उपयोगी – ramzyo

उत्तर

1

आपके विचार के साथ कुछ भी गलत नहीं है। लेकिन अगर मुझे विधि कॉल से स्थानीय वार्स को अलग करने में परेशानी हो रही थी, तो शायद मैं हमेशा () के तरीकों पर हमेशा उपयोग करने के लिए मजबूर हूं। (काम पर मेरी टीम ने हमारे कोडिंग मानकों के इस हिस्से को बनाने पर चर्चा की है)।

a = thing # var 
b = thing() # method 

इसका संभावित लाभ दूसरों के लिए पठनीयता है। कोई आपके अग्रणी _ पर आश्चर्यचकित हो सकता है, लेकिन सभी विधि कॉल पर () का उपयोग करके सभी को स्पष्ट होना चाहिए।

+0

क्या आप केवल तर्क के बिना विधि कॉल के साथ ब्रैकेट का उपयोग करते हैं या ** सभी ** विधि कॉल के साथ कोई फर्क नहीं पड़ता कि कितने तर्क पारित किए गए हैं? –

+0

** सभी ** विधि कॉल के साथ। (मैं वास्तव में खुद को सख्त नहीं कर रहा हूं, लेकिन काम पर कुछ लोग इसके लिए दबाव डाल रहे हैं, और मुझे लगता है कि यह उपर्युक्त मामलों में सहायक हो सकता है।) – bioneuralnet

+0

लेकिन क्या पूरा कोड बहुत जल्द भी नहीं मिलता है? लेकिन इससे सफेद रिक्त स्थान पेश करने के बारे में एक और चर्चा होती है, और ** ** एक समाधान नहीं है। –

3

मेरे अनुभव में, रूबी में अंडरस्कोर-प्रीफिक्स्ड वेरिएबल जावास्क्रिप्ट में अंडरस्कोर-प्रीफिक्स्ड वैरिएबल की तरह हैं: "स्पर्श न करें" ध्वज। अधिक विशेष रूप से, उनका उपयोग तब किया जाता है जब कार्यान्वयनकर्ता ऐसा कुछ कर रहा है जिसे वास्तव में वस्तु के हिस्से के रूप में समझा नहीं जाना चाहिए, या वस्तु के वैचारिक इंटरफ़ेस के रूप में नहीं सोचा जाना चाहिए।

यह जावास्क्रिप्ट दुनिया में अधिक स्पष्ट है, जहां कोई अंडरस्कोर के साथ एक चर को उपसर्ग करके "निजी" अनुकरण कर रहा है। वे एन्कोडिंग कर रहे हैं कि उस वस्तु का हिस्सा है जो हुड के नीचे है और बाहर से ऑब्जेक्ट को देखते समय अनदेखा किया जा सकता है।

रूबी में, मैंने केवल इसे कैश या सिंगलटन इंस्टेंस जैसी चीज़ों के साथ देखा है - ऐसी चीज जो आपके ऑब्जेक्ट के उपभोक्ताओं के लिए अदृश्य होनी चाहिए। गैर-अंडरस्कोर वेरिएबल्स वे चीजें हैं जो आपके ऑब्जेक्ट का उपयोग करने वाले लोगों को जानना चाहती हैं।

किसी भी मामले में, वे काफी दुर्लभ प्रतीत होते हैं, और मैं तब तक उनसे बचूंगा जब तक आप अगले व्यक्ति को सिग्नल भेजना नहीं चाहते हैं, जिसमें कुछ अतिरिक्त जादू या वूडू हो रहा है।

विधि कॉल के लिए एक भेद बनाने के लिए, यदि आप चिंतित हैं कि एक विधि और स्थानीय चर के बीच भ्रम हो सकता है, तो मैं विधि को self पर स्पष्टीकरण के लिए कॉल करूंगा। उदाहरण के लिए:

def foo 
    ... 
end 

def some_method 
    foo # method 
    bar # variable 
end 

इस किसी भी कारण से स्पष्ट नहीं लगता है, तो आप

def some_method 
    self.foo 
    bar 
end 
+0

धन्यवाद में लिखा गया है। लेकिन मुझे लगता है, विधि कॉल के लिए 'self.' का उपयोग करके खुद को भ्रमित करने जा रहा है। एक वर्ग (उदाहरण नहीं) विधि की परिभाषा 'def self.foo' नहीं है? जैसा कि मैं बहुत ही कम उपयोग कर रहा हूं, एक 'स्वयं' मेरी आंख को पकड़ लेगा और मुझे लगता है कि मुझे कक्षा विधि परिभाषा का सामना करना पड़ रहा है। –

+0

हां, यह है, लेकिन कुंजी 'स्वयं' के दायरे को समझना है। याद रखें, रुबी में, सबकुछ एक वस्तु है - कहें, सी ++ में, क्लास ऑब्जेक्ट जैसी कोई चीज़ नहीं है, केवल उदाहरण जो क्लास परिभाषा से बने हैं। व्यावहारिक रूप से, रनटाइम पर, कोई वर्ग नहीं है, केवल डेटा के एक सामान्य सेट के आसपास विधियों का संग्रह है। रूबी में, कक्षाएं भी उदाहरण हैं। जब आप कक्षा को परिभाषित कर रहे हैं, तो 'self' यह _class_ उदाहरण है, और जब आप किसी विधि में होते हैं, तो' self' उस वर्ग का _instance_ है। मुझे पता है कि यह उलझन में है - समझाना मुश्किल है ... – Matt

+0

मुझे नहीं पता, क्या यह समझाना मुश्किल है। मेरे लिए यह तार्किक और परिणामस्वरूप है क्योंकि यह रूबी में किया जाता है। वैसे भी, इसे स्पष्ट करने की कोशिश करने के लिए धन्यवाद :) –

1

साथ के रूप में कैसे उदाहरण चर उनके सामने @ संकेत है देखकर स्पष्ट कर सकते हैं, और वैश्विक चर $ संकेत है उनके सामने पहले से ही रूबी में, संभवतः चरम नामों के सामने एक अंडरस्कोर चरित्र डालना अनावश्यक है। ऐसा कहा जा रहा है, मुझे नहीं लगता कि यह एक बुरा अभ्यास है। यदि यह आपको रूबी में अपना कोड पढ़ने या लिखने में मदद करता है, तो आपको इसका उपयोग करना चाहिए।

मैंने कभी-कभी रूबी कोड देखा है जहां कक्षा में एक उदाहरण विधि के लिए तर्क के सामने एक अंडरस्कोर है। जैसे:

def my_method(_argument1) 
    # do something 
end 

और मुझे लगता है कि यह स्वयं की विशेषताएँ है, रेल में एक मॉडल फ़ाइल की तरह, उदाहरण के लिए, यह उपयोगी है ताकि आप जानते हैं कि आप के साथ काम कर रहे हैं हो सकता है हो सकता है कि जब आप एक वर्ग के साथ काम कर रहे हैं एक वैरिएबल जिसे क्लास/मॉडल से संबंधित गुणों में से एक के विपरीत विधि में पारित किया गया है।

+1

केवल विधि तर्क के साथ अंडरस्कोर का उपयोग करना, एक अच्छी बात प्रतीत होती है। इसे साझा करने के लिए धन्यवाद। –

+0

यदि आपकी विधियां इतनी लंबी हैं कि स्क्रीन पर पैरामीटर सूची अब दिखाई नहीं दे रही है, तो आपको उन्हें अंडरस्कोर के साथ विभाजित नहीं करना चाहिए, आपको उन्हें छोटे होने के लिए दोबारा प्रतिक्रिया देना चाहिए। –

+0

@ JörgWMittag - यदि आपने मेरा विवरण पढ़ा है, तो मैंने विधियों की लंबाई या पैरामीटर की संख्या के बारे में कुछ भी नहीं कहा है, मैंने बस कहा है कि क्लास इंस्टेंस विधि लिखते समय यह सहायक हो सकता है कि ये चर इस विधि के लिए तर्क हैं वर्ग की एक विधि या विशेषता का विरोध किया। फिर, यह जरूरी नहीं है लेकिन कभी-कभी सहायक हो सकता है। – Batkins

3

इस प्रश्न का मौजूदा उत्तर अब कुछ साल पुराना है, और सम्मेलन बदल गए हैं। आपको केवल एक अग्रणी अंडरस्कोर (_some_param), या एक स्टैंडअलोन अंडरस्कोर (_) का उपयोग करना चाहिए, यह इंगित करने के लिए कि आपको मूल्य की परवाह नहीं है। rubocop स्टाइल लिनिंग टूल एक "बेकार असाइनमेंट" के बारे में बताएगा यदि आप एक चर निर्दिष्ट करते हैं लेकिन इसका उपयोग नहीं करते हैं, लेकिन यह एक अग्रणी अंडरस्कोर के साथ चर को अनदेखा कर देगा। यह आपको स्पष्ट रूप से इंगित करने की अनुमति देता है कि आपको मूल्य की परवाह नहीं है और इसका उपयोग करने का इरादा नहीं है।

यहाँ एक RSpec संदर्भ में कुछ हद तक एक-काल्पनिक उदाहरण का उपयोग-मामला है:

describe 'login' do 
    let(:user) { FactoryGirl.create(:user, login: 'bob') } 
    it 'must be unique' do 
    _user1 = user 
    user2 = User.new login: 'bob' 
    expect(user2.valid?).to be_false 
    end 
end 

यहाँ हम यह दर्शाता रहे हैं हमारे user Memoization सहायक एक पक्ष प्रभाव है और कुछ देता है कि है, लेकिन हम परवाह नहीं है इसके बारे में।आप, साथ ही काम पूरी तरह से छोड़ सकता है, लेकिन अपने आप में एक लाइन पर एक नंगे user देखकर अजीब लग रहा है और स्पष्ट रूप से इरादा प्रकट नहीं करता है:

describe 'login' do 
    let(:user) { FactoryGirl.create(:user, login: 'bob') } 
    it 'must be unique' do 
    user 
    user2 = User.new login: 'bob' 
    expect(user2.valid?).to be_false 
    end 
end 

अन्य परिदृश्यों iterators में मूल्यों की अनदेखी, या एक विधि अधिभावी शामिल जहां आप मूल विधि हस्ताक्षर रखना चाहते हैं लेकिन कुछ मानों की परवाह नहीं करते हैं:

def greet(name, _title) 
    puts "Hi, #{name}!" 
end 
+1

सबसे आम तरीका आप ' यह देखेंगे कि यह 'ऐरे' समानांतर असाइनमेंट के माध्यम से है। जैसे एक समारोह (वास्तव में एक 'लंबाई 3 की Array')" 3 मूल्यों रिटर्न "और आप पहले चर का उपयोग करने के लिए नहीं जा रहे हैं, आप लिखते हैं: ' _, myvar2, myvar3 = three_arg_function' या '_myvar1, myvar2, myvar3 = three_arg_function' – supermoogle

संबंधित मुद्दे