2013-05-22 5 views
9

शुरुआती रूबी प्रश्न में वास्तव में स्थानीय चर का उपयोग कैसे करें। इस कोड को बदलने का सबसे आसान तरीका क्या है, लेकिन ब्लॉक को पूरी तरह बरकरार रखने वाले को छोड़कर, जो साइड इफेक्ट को समाप्त करता है?रूबी प्रो/लैम्ब्डा

$ irb 
irb(main):001:0> x = lambda {|v| x=2 
irb(main):002:1> v} 
=> #<Proc:[email protected](irb):1> 
irb(main):003:0> x.call(3) 
=> 3 
irb(main):004:0> x 
=> 2 

यह सबसे सरल उदाहरण मैं या "एक्स को प्रोक असाइन नहीं करते" "काम निकालें" मेरी समस्या को वर्णन करने के ईजाद सकता है, इसलिए है कि मैं के लिए क्या देख रहा हूँ नहीं है।

मैं एक प्रो (या लैम्बडा) में स्थानीय चर सेट करना चाहता हूं जिसे मूल संलग्नक क्षेत्र को प्रभावित किए बिना असाइन किया जा सकता है। मैं ब्लॉक को लपेटने के लिए गतिशील रूप से कक्षा या मॉड्यूल बना सकता था, लेकिन ऐसा लगता है कि इस तरह की मूल चीज़ के लिए ओवरकिल लगता है।

मैं क्या कर रहा हूँ के बराबर अजगर:

def x(v): 
    x = 2 # this is a local variable, what a concept 
    return v 
+0

क्या आपने बाहरी चर के समान नाम का उपयोग नहीं करने का प्रयास किया है? बाहरी क्षेत्र में घोषित होने पर –

+0

'x' एक बंद चर है। क्या आपके पास ऐसी शर्त है जो इन चरों में से किसी एक को नामित करने से रोकती है, जैसे '_x'? आप रूबी भाषा में अन्यथा मौलिक उम्मीद को अक्षम करने की कोशिश कर रहे हैं। – tadman

+0

स्पष्ट रूप से विधियों में स्थानीय चर होना संभव है। क्या यह एकमात्र भाषा निर्माण है जो वीएम में एक नया व्याख्यात्मक गुंजाइश बनाता है? यदि ऐसा है, ऐसा लगता है कि 'Proc' और 'lambda' सस्ते हैं कि इन्हें उचित कार्यात्मक प्रोग्रामिंग करने के लिए उपयोग नहीं किया जा सकता है। – wberry

उत्तर

25

कभी कभी यह वांछित व्यवहार है:

total = 0 
(1..10).each{|x| total += x} 
puts total 

लेकिन कभी कभी यह आकस्मिक है और आप एक बाहर चर जो एक ही नाम है करने के लिए होता के साथ गड़बड़ करने के लिए नहीं करना चाहती। उस स्थिति में, अर्धविराम के साथ पैरामीटर की सूची का पालन करें और ब्लॉक-स्थानीय चर की एक सूची का पालन करें:

x = lambda{|v; x| x = 2; v} 
p x.call(3) #3 
p x #<Proc:[email protected]:2 (lambda)> 
+2

तर्क सूची में स्थानीय चर को परिभाषित करने पर अच्छी कॉल! यह ठीक से पूरा करना चाहिए कि ओपी को बाध्यकारी से इसे मुक्त करने के बिना क्या चाहिए। –

+4

पवित्र बकवास। मैं हर दिन कुछ नया सीखता हूं - यह नहीं पता था कि आप इस ओ.ओ – nzifnab

+0

जैसे अर्धविराम के साथ तर्क सूची में स्थानीय चर "घोषित" कर सकते हैं मुझे एक वाक्यविन्यास त्रुटि मिल रही है, क्यों? http://pastebin.no/z3415 – Dog

6

इस का कारण यह है कि लैम्ब्डा अपने को परिभाषित गुंजाइश (नहीं अपने बुला गुंजाइश) के लिए बाध्य है, और एक पूर्ण बंद, है जो , अन्य चीजों के साथ, स्थानीय चर x शामिल है। आप वास्तव में चाहते हैं कि यहां एक अनबाउंड प्रो है, बिना किसी विशेष बाध्यकारी के कॉल करें और कॉल करें। यह ऐसा कुछ नहीं है जो रूबी डिजाइन द्वारा बहुत आसानी से करता है (यह eval के साथ संभव है, लेकिन यह एक ब्लॉक से कम है और एक स्ट्रिंग कथन का अधिक है)। प्रोसेस, लैम्ब्डा, और ब्लॉक सभी अपने परिभाषित दायरे से बंधे हैं। लेक्सिकल गुंजाइश केवल कक्षाओं, मॉड्यूल और विधियों पर स्थापित है; ब्लॉक/procs/lambdas/कुछ और नहीं पर।

यह ध्यान देने योग्य है कि पायथन पहले स्थान पर लैम्बडास में असाइनमेंट की अनुमति नहीं देता है।

+0

eval संभावना दिलचस्प है। लेकिन क्या वह केवल कुछ भी करने के दायरे में चर को बांध देगा? मुझे लगता है कि मूल रूप से प्रदर्शन दंड के लिए राशि होगी। – wberry

+0

हाँ, पायथन का 'लैम्ब्डा' दुर्भाग्य से इस तथ्य से कमजोर है कि यह एक एकल * अभिव्यक्ति * को प्रतिबिंबित करता है, जो कि असाइनमेंट (और 'जबकि' लूप और अन्य * कथन *) में किए जाने से रोकता है। यह एक वाक्य रचनात्मक कारण है। – wberry

+0

सही। रुबी में निष्पादित सब कुछ * कुछ * गुंजाइश है, भले ही वह दायरा खाली हो। –