2009-12-19 5 views
6

रूबी में, सब कुछ एक वस्तु माना जाता है। लेकिन मैं की तरहरूबी फ़ंक्शन ऑब्जेक्ट प्राप्त करना

def f 
    "foo" 
end 

अजगर के विपरीत, समारोह वस्तु हमेशा की तरह परिभाषित करने के लिए एक बड़ी समस्या है, च समारोह परिणाम, नहीं समारोह ही है। इसलिए, f(), f, ObjectSpace.f सभी "foo" हैं। f.methods केवल स्ट्रिंग विधि सूची देता है।

मैं फ़ंक्शन ऑब्जेक्ट को कैसे एक्सेस करूं?

+0

यह (कई) चीजों में से एक है जो मुझे रूबी में बेर्सक करता है। आप नाम के बिना किसी फ़ंक्शन को नाम से संदर्भित नहीं कर सकते हैं। मेरे गाय ऑर्कर्स के साथ इस बारे में तर्क है। –

+0

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

+1

@ जोनाथन: आप इसे कॉल किए बिना किसी विधि का नाम देख सकते हैं। एक विधि का नाम एक प्रतीक है। तो इस विधि का नाम ': f' है। रूबी अपनी मेटाप्रोग्रामिंग क्षमताओं के लिए बहुत प्रसिद्ध है, और विधि नाम हर समय उपयोग किया जाता है। – Chuck

उत्तर

10

आप बस method विधि का उपयोग करें। यह Method उदाहरण है कि विधि के साथ मेल खाता है वापस आ जाएगी। कुछ उदाहरण:

>> def f 
>> "foo" 
>> end 
=> nil 
>> f 
=> "foo" 
>> method(:f) 
=> #<Method: Object#f> 
>> method(:f).methods 
=> [:==, :eql?, :hash, :clone, :call, :[], ...] 
>> class SomeClass 
>> def f 
>>  "bar" 
>> end 
>> end 
=> nil 
>> obj = SomeClass.new 
=> #<SomeClass:0x00000001ef3b30> 
>> obj.method(:f) 
=> #<Method: SomeClass#f> 
>> obj.method(:f).methods 
=> [:==, :eql?, :hash, :clone, :call, :[], ...] 

आशा इस मदद करता है।

+0

ओह, और विधि ऑब्जेक्ट एक प्रो-जैसी ऑब्जेक्ट है, इसलिए आप 'obj.method (: f) .call() 'या' obj.method (: f) [] 'कॉल करने के लिए करते हैं यह। या, रूबी 1.9.1 पर; 'Obj.method (: च)।()'। – henrikhodne

0

आप एक वस्तु जो रनटाइम पर कि समारोह के अनुरूप होगा प्राप्त कर सकते हैं, लेकिन जहां तक ​​मैं जानता हूँ कि वहाँ के रूप में अजगर आप समारोह/वर्ग परिभाषा वहीं करने की अनुमति देता है क्या करने के लिए कोई बराबर है।

उम्मीद है कि कोई मुझे गलत साबित करेगा, लेकिन मैं इसे कभी खींचने में सक्षम नहीं हूं।

1

रूबी में, जो आप पूछ रहे हैं वह समझ में नहीं आता है। (यह पाइथन, जावास्क्रिप्ट, जावा और सी # जैसी भाषाओं में समझ में आता है।)

रूबी में, आप एक वर्ग को बता सकते हैं कि उसे किस संदेश का जवाब देना चाहिए और किस तरीके से उन्हें उन संदेशों का जवाब देना चाहिए। कक्षा में एक विधि को परिभाषित करने के लिए एक वर्ग को बताने का सबसे आम तरीका है। लेकिन फिर, कि बस मतलब यह है: जब कोई व्यक्ति इस उदाहरण के लिए संदेश f भेजता है, यहाँ व्यवहार है कि उदाहरण के साथ जवाब चाहिए। कोई फंक्शन ऑब्जेक्ट नहीं है।

आप एक प्रतीक (method_name = :foo) जैसी चीजें कर सकते हैं और एक बंद (method = proc { obj.foo }) प्राप्त कर सकते हैं।

+0

यदि एफ कोई ऑब्जेक्ट नहीं है, तो ऑब्जेक्टस्पेस में क्यों है? – mykhal

+0

तरीके वस्तुएं हैं। वे केवल ऑब्जेक्ट्स नहीं हैं रनटाइम आपको तब तक पहुंचने की इजाजत देता है जब उन्हें अभी भी परिभाषित किया जा रहा है। यदि आप ऐसा करना चाहते हैं तो पाइथन से चिपके रहें। –

+0

वास्तव में, एक विधि वर्ग है कि सभी विधियों का एक उदाहरण है। जब आप रूबी में 'obj.some_method' करते हैं, तो यह संदेश obj को भेजता है, जो मिलान विधि के लिए इसकी विधि सूची में दिखता है, और उसके बाद उस विधि को कॉल करता है। अगर यह विधि नहीं मिल पाती है, तो यह 'method_missing'' कहती है। – henrikhodne

1

यह एक कार्य नहीं है; यह एक वस्तु का एक तरीका है। यदि आप एक विधि का प्रतिनिधित्व एक वस्तु प्राप्त करना चाहते हैं, तो आप इसके लिए मालिक वस्तु से पूछते हैं: उदाहरण के लिए

someobj.method :f 

:

plus_one = 1.method :+ 
plus_one[9] # 10 
+0

'def f; "Foo"; अंत 'वास्तव में एक समारोह नहीं है? – mykhal

+0

संकल्पनात्मक रूप से, नहीं - यह एक विधि है। यह मूल रूप से रूबी में एक मालिक के लिए बाध्य है। सच्चे कार्यों के बराबर निकटतम रूबी प्रक्रिया होगी। – Chuck

3

विधि method आप एक Method वस्तु

f = obj.method :f 
puts f.call # or f[] 
दे देंगे

यह f ओबीजे से जुड़ा हुआ है। तुम भी एक अबाध विधि प्राप्त कर सकते हैं:

unbound_plus = Fixnum.instance_method('+') 
plus_2 = unbound_plus.bind(2) 

(वहाँ भी एक अनबाइंड विधि है)

+0

तो आप कहेंगे कि मेरा एफ अनबाउंड विधि है। यह उचित दिखता है। हालांकि, तथ्य यह है कि मेरे एफ एल ऑब्जेक्टस्पेस विधियों (जो अन्यथा ऑब्जेक्ट्स लौटाते हैं) के रूप में कार्य करते हैं – mykhal

+0

अच्छी तरह से भ्रमित कर रहे हैं, यह अभी भी मेरे प्रश्न का उत्तर नहीं देता है, मैं विधि एफ के रूप में अपने एफ का इलाज कैसे करूं – mykhal

+0

@mykhal: जिस विधि को आप परिभाषित करते हैं शीर्ष स्तर ऑब्जेक्ट का एक उदाहरण विधि बन जाता है, इसलिए ऑब्जेक्टस्पेस (जो एक वस्तु है, भाषा में बाकी सब कुछ की तरह) विधि भी प्राप्त करती है। आपको ऑब्जेक्टस्पेस के बाहर से इसे सामान्य रूप से कॉल करने में सक्षम नहीं होना चाहिए, हालांकि - विधियों ने डिफ़ॉल्ट रूप से डिफ़ॉल्ट होने के तरीके को परिभाषित किया है। – Chuck

2

अच्छी तरह से मैं इस सवाल का जवाब मिल गया है अपने आप को

obj = method :f 

प्रेरणा :)

के लिए आप सभी को धन्यवाद
+0

यह आपको विधि देता है, लेकिन शुद्ध कार्य नहीं। 'प्रो' ऑब्जेक्ट बनाना संभवतः आप जो चाहते हैं उसके करीब है। एक विधि को हमेशा एक रिसीवर की आवश्यकता होती है, क्योंकि यह किसी ऑब्जेक्ट से जुड़ा होता है, इसलिए एक proc (edure) स्वयं एक ऑब्जेक्ट होता है और इस प्रकार इसे केवल फ़ंक्शन की तरह कहा जा सकता है। – akuhn

+0

@ एड्रियन यह अनबाउंड विधि देता है। अपने आप को आजमाएं: 'रूबी-ए' डी एफ; "Foo"; समाप्त; obj = विधि: एफ; obj.call'' – mykhal

0

आप एक Proc वस्तु बनाने चाहिए एक समारोह वस्तु चाहते हैं, तो

f = Proc.new { |x| x * 2 } 

आप या तो

f.call(8) # => 16 

या

f[8] # => 16 

आप भी इस सुविधा का उपयोग कर सकते हैं का उपयोग कर फ़ंक्शन को कॉल करें map ऑपरेशन

में ऑब्जेक्ट
[1, 2, 3, 4, 5].map(&f) # => [2, 4, 6, 8, 10]