2010-07-26 7 views
57

कोई मुझे बता सकते हैं क्या(रूबी में क्या भेजा जाता है) करते हैं?

send("#{Model.find...}") 

है और करता है?

+1

इस कोड की पूरी लाइन है: आप स्केलेबल दृश्य जो के साथ वस्तुओं के सभी प्रकार के साथ काम करते हैं लिखने के लिए? मेरा मतलब है, 'भेजने' से पहले कुछ भी नहीं है? – giraff

उत्तर

65

send एक वस्तु उदाहरण और वर्ग पदानुक्रम में अपने पूर्वजों जब तक कुछ विधि से प्रतिक्रिया करता है (क्योंकि इसके नाम पहला तर्क से मेल खाता है) के लिए एक संदेश भेजता है।

व्यवहार में, उन पंक्तियों के बराबर हैं:

1.send '+', 2 
1.+(2) 
1 + 2 

ध्यान दें कि send नजरअंदाज दृश्यता की जाँच करता है, ताकि आप निजी तरीकों, भी (इकाई परीक्षण के लिए उपयोगी) कह सकते हैं।


यदि वाकई भेजने से पहले कोई चर, इसका मतलब है कि वैश्विक वस्तु प्रयोग किया जाता है:

send :to_s # "main" 
send :class # Object 
+0

ओह, मैं देखता हूं, इसलिए कोई व्यक्ति भेजने का उपयोग कर सकता है अगर कोई कुछ समय की तरह स्टोर करना चाहता था, तो डेटाबेस की संख्या स्थिर रूप से दिनों की संख्या कहने के बजाय। –

+2

सच है, आप इसका उपयोग उन नामों के साथ कॉल विधि के लिए कर सकते हैं, जिन्हें गणना की जाती है, स्थिर नहीं। (हालांकि, निजी तरीकों को कॉल करने से बचने के लिए आपको अप्रतिबंधित उपयोगकर्ता इनपुट की अनुमति नहीं देनी चाहिए ... हालांकि, आप उन्हें एक अद्वितीय उपसर्ग दे सकते हैं: 'user_method _' + methodname, * args भेजें) – giraff

+0

अच्छा उपयोग केस यह हो सकता है कि आप चाहें एक संरक्षित वर्ग विधि का परीक्षण करने के लिए, आप इसे क्लास-इन टेस्ट फ़ाइल के बाहर कॉल कर सकते हैं .. –

69

भेजने एक गहरे लाल रंग का (रेल) के बिना विधि नाम से एक और तरीका आह्वान करने के लिए अनुमति देता है।

प्रलेखन

से
class Klass 
    def hello(*args) 
     "Hello " + args.join(' ') 
    end 
    end 
    k = Klass.new 
    k.send :hello, "gentle", "readers" #=> "Hello gentle readers" 

http://corelib.rubyonrails.org/classes/Object.html#M001077

+3

ग्रेट उत्तर, वर्बोज़ स्वीकृत उत्तर से अधिक स्पष्ट है। –

33

मैं .send विधि के साथ लगता है कि सबसे उपयोगी सुविधा की है कि यह गतिशील रूप से कॉल कर सकते हैं है विधि पर। यह आपको लिखने का बहुत सा बचा सकता है। .send विधि के सबसे लोकप्रिय उपयोग में से एक गतिशील विशेषताओं आवंटित करने के लिए है। उदाहरण के लिए:

class Car 
    attr_accessor :make, :model, :year 
end 

विशेषताएं नियमित रूप से असाइन करने के लिए एक या एक से

c = Car.new 
c.make="Honda" 
c.model="CRV" 
c.year="2014" 

करने की आवश्यकता होगी .send विधि का उपयोग कर:

c.send("make=", "Honda") 
c.send("model=", "CRV") 
c.send("year=","2014") 

लेकिन यह सब निम्नलिखित के साथ बदला जा सकता है:

अपने रेल एप्लिकेशन मान लिया जाये, उपयोगकर्ता इनपुट से अपनी कार वर्ग के लिए गुण आवंटित करने के लिए की जरूरत है यो यू

c = Car.new() 
params.each do |key, value| 
    c.send("#{key}=", value) 
end 
+0

महान लिंक –

+3

के लिए धन्यवाद इस तरीके से .send का उपयोग अनावश्यक जटिलता को जोड़ता है और अनजाने में कोड में एक बग पेश करना आसान बनाता है। उदाहरण के लिए, उपरोक्त आपके कोड में, यदि आप अपने पैरामीटर हैश (जैसे 'सिलेंडर') में एक नई प्रविष्टि जोड़ते हैं, तो कोड एक अपरिभाषित विधि त्रुटि के साथ विफल हो जाएगा। –

+1

respond_to? वांछित अगर ऐसी त्रुटियों को रोकने के लिए इस्तेमाल किया जा सकता है। –

8

एक और उदाहरण, एंटोनियो झा https://stackoverflow.com/a/26193804/1897857

यदि आप एक वस्तु पर गुण पढ़ने की जरूरत है के लिए इसी तरह कर सकते हैं।

उदाहरण के लिए, यदि आप तार की एक सरणी है, यदि आप उन के माध्यम से पुनरावृति और उन्हें अपनी वस्तु पर कॉल करने के लिए प्रयास करते हैं, यह काम नहीं करेगा।विचारों के लिए

atts = ['name', 'description'] 
@project = Project.first 
atts.each do |a| 
    puts @project.send(a) 
end 
# => Vandalay Project 
# => A very important project 
+0

सरल और आसान स्पष्टीकरण के लिए धन्यवाद! –

+0

धन्यवाद! यही वह जवाब है जिसके बाद मैं हूं। आश्चर्य यह आमतौर पर इस्तेमाल किया जाता है? मैं विरासत कोड में कुछ ऐसा ही आया, मुझे यकीन नहीं है कि मुझे इसके साथ रहना चाहिए। @ माइक वलानो –

+0

@ बी-लियू मैंने इसे नए कोड में अनुभवी डेवलपर्स द्वारा उपयोग किया है। 'Define_method' का उपयोग करते समय यह सहायक भी हो सकता है: https://apidock.com/ruby/Module/define_method। –

0

एक और उपयोग के मामले:

atts = ['name', 'description'] 
@project = Project.first 
atts.each do |a| 
    puts @project.a 
end 
# => NoMethodError: undefined method `a' 

हालांकि, अगर आप वस्तु को तार send कर सकते हैं

<%= link_to 
    send("first_part_of_path_{some_dynamic_parameters}_end_path", 
    attr1, attr2), .... 
    %> 

की अनुमति दें।

render 'your_view_path', object: "my_object" 
संबंधित मुद्दे