2011-08-23 9 views
5

मेरे पास यह है:रूबी में विधियों के लिए स्टेटिक स्थानीय चर?

def valid_attributes 
    { :email => "some_#{rand(9999)}@thing.com" } 
end 

रुपेक परीक्षण के लिए सही है? लेकिन मैं ऐसा कुछ करना चाहता हूं:

def valid_attributes 
    static user_id = 0 
    user_id += 1 
    { :email => "some_#{user_id}@thing.com" } 
end 

मैं नहीं चाहता कि user_id कहीं से भी पहुंच योग्य हो लेकिन उस विधि, रूबी के साथ यह संभव है?

+2

संक्षिप्त उत्तर नहीं है, रुबी में 'स्थिर 'जैसी कोई चीज़ नहीं है। डेटाबेस को अपनी ऑटो-वृद्धिशील कुंजी को क्यों न संभालें? – Emily

+0

क्योंकि यह रुपयेपीई परीक्षण के लिए मान्य विशेषताओं को उत्पन्न करने का एक तरीका है, और कुछ चीजें अद्वितीय होनी चाहिए। – Zequez

उत्तर

6

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

मुझे लगता है कि आप वास्तव में यहां क्या देख रहे हैं कारखानों है। factory_girl जैसे कुछ का उपयोग करने का प्रयास करें, जो बहुत अधिक परीक्षण को अधिक आसान बना देगा।

सबसे पहले, आप को बनाने के लिए जो कुछ भी वस्तु के प्रकार यह आप परीक्षण कर रहे है एक कारखाना स्थापित करना चाहते हैं, और ईमेल विशेषता के लिए एक दृश्य का उपयोग करें:

FactoryGirl.define do 
    factory :model do 
    sequence(:email) {|n| "person#{n}@example.com" } 
    # include whatever else is required to make your model valid 
    end 
end 

तब, जब आप मान्य गुण की जरूरत है, आप

Factory.attributes_for(:model) 

का उपयोग तुम भी उपयोग कर सकते हैं Factory.create और Factory.build बचाया और मॉडल के बिना सहेजे गए उदाहरण बना कर सकते हैं।

getting started document में कई और विशेषताओं के स्पष्टीकरण के साथ-साथ आपके प्रोजेक्ट में कारखानों को जोड़ने के निर्देशों के बारे में जानकारी है।

+0

धन्यवाद! मैं निश्चित रूप से उस मणि की जांच करूँगा! ^^ – Zequez

0

रूबी में स्थानीय चर, आवृत्ति चर, वर्ग चर और वैश्विक चर हैं। उनमें से कोई भी फिट नहीं है जो आप कर रहे हैं।

आपको शायद जो चाहिए वह एक सिंगलटन है जो user_id को संग्रहीत करता है, और आपको हर बार एक नया आईडी नंबर देता है। अन्यथा, आपका कोड थ्रेड-सुरक्षित नहीं होगा।

4

मैं एक उदाहरण चर का उपयोग करेंगे:

def validator_factory 
    user_id = 0 
    lambda do 
    user_id += 1 
    { :email => "some_#{user_id}@thing.com" } 
    end 
end 

valid_attributes = validator_factory 

valid_attributes.call #=> {:email=>"[email protected]"} 
valid_attributes.call #=> {:email=>"[email protected]"} 

इस तरह user_id बाहर तक नहीं पहुँच पाएंगे:

def valid_attributes 
    @user_id ||= 0 
    @user_id += 1 
    { :email => "some_#{@user_id}@thing.com" } 
end 
4

आप एक बंद उपयोग कर सकते हैं।

7

यह एक बंद करने का मामला है। लैम्ब्डा में इस

 
lambda { 
    user_id = 0 

    self.class.send(:define_method, :valid_attributes) do 
    user_id += 1 
    { :email => "some_#{user_id}@thing.com" } 
    end 

}.call 

रैपिंग सब कुछ प्रयास करें चर लैम्ब्डा में परिभाषित केवल दायरे में अस्तित्व के लिए अनुमति देता है। आप अन्य विधियों को भी जोड़ सकते हैं। सौभाग्य!

+0

मैंने इसके बाद दो 'p valid_attributes' जोड़कर अपना कोड आज़माया, लेकिन मुझे शून्य त्रुटि के लिए' त्रुटि NoMethodError: अपरिभाषित विधि '+ मिली: NilClass'। मुझे लगता है कि 'def' के अंदर' user_id' एक स्थानीय चर है जिसे 'शून्य' के रूप में प्रारंभ किया गया है। शायद आप किसी अन्य तरीके से बंद का उपयोग कर सकते हैं। :) –

+0

हाय सोनी, मैं डीफ़ के बारे में भूल गया हूँ।मैंने इसे पहले से defin_method में बदल दिया है, इसलिए अब यह user_id तक पहुंचने में सक्षम होना चाहिए। लैम्ब्डा के भीतर परिभाषित अन्य विधियां इस तरह से user_id चर साझा कर सकती हैं। – RubyFanatic

+1

ठीक है, लेकिन आपको 'self.class.send: define_method,: valid_attributes' का उपयोग करना चाहिए, क्योंकि' define_method' एक निजी क्लास विधि है। वैसे भी, मैं [मेरा] (http://stackoverflow.com/questions/7168400/static-local-variables-for-methods-in-ruby/7169076#7169076) पर अपना समाधान पसंद करता हूं, क्योंकि मेरे मामले में 'valid_attributes' है एक proc (जिसे 'कॉल' या '[]' 1.8.7 में बुलाया जाना चाहिए), और आपके मामले में यह एक वास्तविक विधि है। –