2011-01-11 13 views
137

मैं some_instance.send की अवधारणा को समझता हूं लेकिन मैं यह समझने की कोशिश कर रहा हूं कि आप इन दोनों तरीकों को क्यों कॉल कर सकते हैं। रूबी कोन्स का मतलब है कि एक ही काम करने के कई अलग-अलग तरीकों को प्रदान करने से परे कुछ कारण है। उपयोग के दो उदाहरण यहां दिए गए हैं:रूबी बनाम __send__

class Foo 
    def bar? 
    true 
    end 
end 

foo = Foo.new 
foo.send(:bar?) 
foo.__send__(:bar?) 

किसी को भी इस बारे में कोई जानकारी है?

उत्तर

213

कुछ कक्षाएं (उदाहरण के लिए मानक लाइब्रेरी की सॉकेट क्लास) अपने send विधि को परिभाषित करती है जिसका Object#send से कोई लेना देना नहीं है। इसलिए यदि आप किसी भी वर्ग की वस्तुओं के साथ काम करना चाहते हैं, तो आपको सुरक्षित पक्ष पर रहने के लिए __send__ का उपयोग करना होगा।

अब सवाल छोड़ देता है, send क्यों है और न केवल __send__ है। अगर वहां केवल __send__ नाम send का उपयोग किसी भी भ्रम के बिना अन्य वर्गों द्वारा किया जा सकता है। इसका कारण यह है कि send पहले अस्तित्व में था और केवल बाद में यह महसूस किया गया कि send का नाम अन्य संदर्भों में भी उपयोगी रूप से उपयोग किया जा सकता है, इसलिए __send__ जोड़ा गया था (यह वही बात है जो id और object_id के साथ हुई थी)।

+7

इसके अलावा, [बेसिकऑब्जेक्ट] (http://ruby-doc.org/core/BasicObject.html) (रुबी 1.9 में पेश किया गया) केवल '__send__' है, 'भेजना' नहीं है। –

+0

अच्छा जवाब।यदि यह 'public_send' का उल्लेख किया गया है, तो भी बेहतर हो सकता है, जो अक्सर 'भेजने' के लिए बेहतर होता है। –

29

आप वास्तव मेंsend की जरूरत है, जैसे कि यह सामान्य रूप से है, तो आप __send__ का प्रयोग करेंगे चाहिए व्यवहार करने के लिए है क्योंकि यह (यह नहीं होना चाहिए) ओवरराइड किया जा नहीं होगा। __send__ का उपयोग मेटाप्रोग्रामिंग में विशेष रूप से उपयोगी होता है, जब आप नहीं जानते कि कक्षा को किस तरीके से छेड़छाड़ की जा रही है। यह send overriden हो सकता है।

घड़ी:

चेतावनी:

class Foo 
    def bar? 
    true 
    end 

    def send(*args) 
    false 
    end 
end 

foo = Foo.new 
foo.send(:bar?) 
# => false 
foo.__send__(:bar?) 
# => true 

आप __send__ ओवरराइड हैं, रूबी एक चेतावनी उत्सर्जित करेगा `__send__ 'को फिर से परिभाषित कर सकते हैं कारण गंभीर समस्याओं

कुछ मामलों में जहां यह send ओवरराइड करने के लिए उपयोगी होगा जहां वह नाम उपयुक्त होगा, जैसे संदेश pas गायन, सॉकेट कक्षाएं, आदि

9

__send__ मौजूद है इसलिए इसे दुर्घटना से अधिक लिखा नहीं जा सकता है।

क्यों send मौजूद है का सवाल है: मैं किसी और के लिए नहीं बोल सकता, लेकिन object.send(:method_name, *parameters)object.__send__(:method_name, *parameters) से अच्छे लग रहा है, तो मैं send का उपयोग जब तक कि मैं __send__ उपयोग करने के लिए जरूरत । क्या दूसरों से

5

अलावा आप पहले से ही बताया है, और क्या कह रही है कि send और __send__ एक ही विधि के दो अन्य नामों में बताएं, आप तृतीय, somwhat अलग संभावना है, जो public_send है में रुचि हो सकती। उदाहरण:

A, B, C = Module.new, Module.new, Module.new 
B.include A #=> error -- private method 
B.send :include, A #=> bypasses the method's privacy 
C.public_send :include, A #=> does not bypass privacy 

अद्यतन: रूबी 2.1, के बाद से Module#include और Module#extend तरीकों, सार्वजनिक हो तो ऊपर के उदाहरण अब काम नहीं होगा।

+0

अच्छा ज्ञान, धन्यवाद! – jaydel

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