2010-04-08 13 views
41

कुछ googling के बाद this discussion से प्रेरित, रूबी में विधियों के बारे में एक बहुत ही सरल सवाल का जवाब नहीं मिला: विधियों के तरीके हैं या नहीं?रूबी में तरीके: ऑब्जेक्ट्स या नहीं?

अलग-अलग राय here और there हैं, और मैं वास्तव में सुनना चाहूंगा, मान लीजिए, एक गहराई से स्पष्टीकरण।

मैं Object#method विधि है, जो एक विधि नाम लेता है और एक Method उदाहरण देता है, लेकिन, दूसरे हाथ पर के बारे में पता कर रहा हूँ, वहाँ एक समान बात आप ब्लॉक के साथ क्या कर सकते हैं उन्हें Proc उदाहरणों में बनाने के लिए है, और ब्लॉक नहीं कर रहे ' टी वस्तुओं, तो क्या तरीकों को अलग करता है?

+0

कार्य रूबी में प्रथम श्रेणी के नागरिक हैं और वस्तुओं में परिवर्तित किया जा सकता है, तो चिंता क्यों करें? मुझे लगता है कि उत्तर बहुत समझने के लिए बहुत कम स्तर लगेगा ... –

+3

क्या वे हैं? आईएमएचओ, तथ्य यह है कि आपको उन्हें वस्तुओं में बदलने की ज़रूरत है, उन्हें प्रथम श्रेणी नहीं बनाते हैं। यही वह जवाब है जो मैं जवाब से भी सीखना चाहता हूं। –

उत्तर

60

तरीके रूबी के वाक्य रचना का एक मूलभूत हिस्सा हैं, लेकिन वे मान कि रूबी कार्यक्रमों पर काम कर सकते हैं नहीं कर रहे हैं। वह है, रूबी के तरीके ऑब्जेक्ट्स स्ट्रिंग्स, संख्याओं और एरे के तरीके में हैं। यह संभव है, हालांकि, विधि ऑब्जेक्ट प्राप्त करने के लिए जो किसी दिए गए विधि, का प्रतिनिधित्व करता है और हम विधि वस्तुओं के माध्यम से अप्रत्यक्ष रूप से विधियों को आमंत्रित कर सकते हैं।

The Ruby Programming Language से:
alt text http://ecx.images-amazon.com/images/I/517LDwIEYwL._SL75_.jpg

+0

हाय, यदि विधियां ऑब्जेक्ट नहीं हैं तो यह कैसे संभव है? 'आईआरबी (मुख्य): 015: 0> डीईएफ़ हाय आईआरबी (मुख्य): 016: 1>" हैलो " आईआरबी (मुख्य): 017: 1> अंत => शून्य आईआरबी (मुख्य): 018: 0> hi.object_id => 22,452,528 आईआरबी (मुख्य): 019: 0> hi.object_id.send हाय => "हाय" आईआरबी (मुख्य): 020: 0> hi.object_id.send (hi) => "हाय" ' –

+11

'hi.object_id' पहले कॉल विधि' हाय' कॉल करता है, और उसके बाद इसके परिणाम का ऑब्जेक्ट_आईडी देता है (जो स्ट्रिंग' हैलो "' है)। –

10

रूबी में, विधियों और ब्लॉक, मूल और प्रथम श्रेणी की वस्तुओं में नहीं हैं। हालांकि, वे वस्तुओं में बहुत आसानी से लपेटा जा सकता है, जैसे कि यह आम तौर पर कोई फर्क नहीं पड़ता।

लेकिन बाहर की कोशिश, और मन में का परिणाम रखने के लिए,

a = Object.method(:new).object_id 
b = Object.method(:new).object_id 
a == b 
=> false 

हास्केल में, मानों (संख्या के साथ-साथ lambdas और कार्यों सहित) प्रथम श्रेणी के मान हैं। भाषा के हर पहलू में, वे सभी समान रूप से व्यवहार किए जाते हैं। रूबी में यह मामला नहीं है, लेकिन इसका अनुमान लगाया जा सकता है।

+0

न्याय, आपका तर्क मेरे जैसा ही था। इसके अलावा, मुझे विधियों को वापस करने के किसी अन्य तरीके से अवगत नहीं है, इसलिए #method (method_name) किसी विधि को संदर्भित करने का एकमात्र तरीका प्रतीत होता है, इसे इसके मूल ऑब्जेक्ट पर नाम से कॉल करने के अलावा। –

+1

आपकी ऑब्जेक्ट_आईडी साबित करने वाली एकमात्र चीज यह है कि वे तुरंत नहीं हैं। 'ए = 1.0.object_id; बी = 1.0.object_id; एक == बी # => झूठी' –

18

आप वास्तव में नहीं बता सकता।

किसी विधि तक पहुंच प्राप्त करने का एकमात्र तरीका #method संदेश को किसी ऑब्जेक्ट को भेजना है, जो तब Method ऑब्जेक्ट लौटाएगा। लेकिन क्या Method विधि को ऑब्जेक्ट कर रहा है? या यह विधि के चारों ओर एक रैपर है? या यह मूल विधि का एक परिवर्तित संस्करण है?

आप नहीं जान सकते: यदि आप किसी विधि को देखना चाहते हैं, तो आपको #method पर कॉल करना होगा, जिस बिंदु पर आप निश्चित रूप से ऑब्जेक्ट प्राप्त करेंगे। से पहले #method कहा गया था, इसलिए आप नहीं देख सकते हैं, इसलिए आप नहीं बता सकते हैं।

कुछ डेटापॉइंट्स: रुबी में, सब कुछ एक मूल्य देता है। def क्या करता है? यह हमेशाnil देता है, Method ऑब्जेक्ट नहीं। और define_method? यह Proc देता है, लेकिन Method नहीं (न ही UnboundMethod)। [नोट: रूबिनीस में, def विधि के संकलित बाइटकोड लौटाता है, लेकिन फिर भी Method ऑब्जेक्ट नहीं देता है।]

यदि आप रुबी भाषा विशिष्टता की धारा 6.1 के चौथे और 5 वें पैराग्राफ (पेज 5-34 और पेज 5 और 6 पर 1-5) देखते हैं, तो आप स्पष्ट रूप से देख सकते हैं कि विधियों के बीच एक अंतर है और वस्तुओं। और यदि आप बिल्टिन कक्षाओं के विनिर्देश को देखते हैं, तो आप पाएंगे कि न तो Method और न ही UnboundMethod वहां हैं, न ही Object#method है। IOW: आप एक पूरी तरह से मानकों-अनुरूप रूबी दुभाषिया का निर्माण कर सकते हैं जिसमें ऑब्जेक्ट्स नहीं हैं।

अब, OTOH ब्लॉक निश्चित रूप से ऑब्जेक्ट्स नहीं हैं। ऐसे कई तरीके हैं करने के लिए ब्लॉक सेProc वस्तुओं का निर्माण, जो तब मूल ब्लॉक (lambda, proc, Proc.new, & sigil) के रूप में ही व्यवहार कर रहे हैं, लेकिन ब्लॉक खुद को ऑब्जेक्ट नहीं है।

इस बारे में सोचें: आप एक फ़ाइल ऑब्जेक्ट बनाने के लिए File.new पर एक स्ट्रिंग पास कर सकते हैं, लेकिन इससे कोई स्ट्रिंग फ़ाइल नहीं बनती है। आप एक ऑब्जेक्ट बनाने के लिए Proc.new पर एक ब्लॉक पास कर सकते हैं, लेकिन इससे कोई ब्लॉक ब्लॉक नहीं होता है।

+0

बस संदर्भ के लिए: http://stackoverflow.com/questions/4294485/how-do-i-reference-a-function-in-ruby/4294660#4294660 –

+2

व्यंग्यात्मक ध्वनि नहीं चाहते हैं, लेकिन एक ब्लॉक क्या है? क्या यह केवल एक .rb फ़ाइल में पाठ का एक टुकड़ा है? –

+0

जोर्ग ने स्पष्ट किया कि बाद में स्टैक ओवरव्लो प्रश्न @ MladenJablanović लिंक में रूबी विधियां ऑब्जेक्ट्स नहीं हैं। यहां उद्धरण दिया गया है: "नोट, हालांकि, विधि और अनबाउंड मोड दोनों विधि के चारों ओर रैपर हैं, विधि ही नहीं। विधि रूबी में ऑब्जेक्ट्स नहीं हैं। (मैंने जो अन्य उत्तरों में लिखा है उसके विपरीत, बीटीडब्ल्यू। मुझे वास्तव में आवश्यकता है वापस जाने और उनको ठीक करने के लिए।) " – Powers

2

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

+2

रूबी के परिप्रेक्ष्य से ऑब्जेक्ट्स हैं। कार्यान्वयन विवरण महत्वपूर्ण नहीं हैं। एक विधि पते और किसी भी अन्य वस्तु की तरह पारित किया जा सकता है। प्रक्रियाएं ऑब्जेक्ट्स भी हैं (और ब्लॉक प्रो/लैम्ब्डा बनाने का सिर्फ एक वाक्य रचनात्मक तरीका हैं)। – simonmenke

0

क्योंकि ब्रांड्स में ब्रांड्स वैकल्पिक हैं, विधि ऑब्जेक्ट आमतौर पर method विधि के माध्यम से विधि ऑब्जेक्ट को स्पष्ट रूप से लाने की आवश्यकता है। हालांकि यदि आप किसी विधि ऑब्जेक्ट को कैप्चर करने का प्रयास करते हैं तो यह स्पष्ट हो जाता है कि यह किसी ऑब्जेक्ट की तरह कार्य करता है। रूबी> = 2.1 के बाद से पहले से लाभ लेना आसान है।

foo = method def foo 
    def a(num) 
    3 * num.to_i 
    end 

    n = yield if block_given? 
    a(n || 3) 
rescue 
    "oops!" 
end 

def foo.bar(num) 
    a(num) 
end 

foo.class #=> Method 
foo() #=> 9 
foo.call #=> 9 
foo.call{2} #=> 6 
foo(){2} #=> 6 
foo.call{ raise "blam!" } #=> "oops!" 
foo.bar(5) #=> 15 

एक के लिए See this gist:

उदाहरण के लिए, यदि आप अपने तरीकों को और अधिक की तरह वे इतनी तरह जावास्क्रिप्ट (जहां कोई कोष्ठक विधि वस्तु है और कोष्ठक विधि कॉल करने के लिए उपयोग किया जाता) में क्या व्यवहार करने के लिए प्राप्त कर सकते हैं परीक्षण के रूप में लिखे गए इन उदाहरणों के साथ संस्करण।

JRL's answer कह रही है कि तरीकों वस्तुओं तार आदि हैं की तरह नहीं हैं, लेकिन विधि वस्तुओं असली, और कोष्ठक के अलावा अन्य कर रहे हैं उद्धरण Matz पुस्तक/no-कोष्ठक बात वे काफी किसी अन्य माणिक वस्तु की तरह काम करते हैं। यह duck-typed language है, इसलिए मैं कहूंगा कि मेरी पुस्तक में ऑब्जेक्ट्स के रूप में योग्यताएं हैं।

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