2016-04-17 9 views
6

द्वारा मॉड्यूल पर कॉल विधि सामान्य रूप से मैं इलीक्सिर और कार्यात्मक प्रोग्रामिंग-भाषाओं के लिए काफी नया हूं।इलीक्सिर - स्ट्रिंग-नाम

एलिक्सीर में, मैं मॉड्यूल नाम पर स्ट्रिंग के रूप में मॉड्यूल पर एक विशिष्ट फ़ंक्शन को कॉल करना चाहता हूं।

मैं काम कर रहा है, जो काफी मैं क्या चाहते हैं करता है निम्नलिखित (बहुत बुरा) कोड मिल गया है करने के लिए:

module_name = elem(elem(Code.eval_file("module.ex", __DIR__), 0), 1) 
apply(module_name, :helloWorld, []) 

यह (मैं यह समझ में कम से कम के रूप में) (पहले से ही संकलित) के मॉड्यूल संकलित वर्तमान निर्देशिका में module.ex। मैं दो tuples में से मॉड्यूल नाम (स्ट्रिंग के रूप में नहीं, यह नहीं जानता कि वास्तव में कौन सा डेटा-प्रकार है) निकालें और विधि helloWorld पर चलाएं।

  1. यह redefining module Balance समान एक चेतावनी प्रिंट:

    इस कोड के साथ दो समस्याएं हैं। मैं निश्चित रूप से उत्पादन में ऐसा नहीं करना चाहता हूं।

  2. AFAIK यह कोड module.ex संकलित करता है। लेकिन जैसा मॉड्यूल.एक्स पहले ही संकलित और लोड हो चुका है, यह नहीं चाहता कि ऐसा हो।

मुझे फ़ाइल नाम से इन मॉड्यूल पर विधियों को कॉल करने की आवश्यकता नहीं है, मॉड्यूल-नाम भी ठीक रहेगा। लेकिन इसे गतिशील, उदाहरण के लिए करना है। कमांड लाइन पर "बुक" दर्ज करना, जांच के बाद, मॉड्यूल मौजूद है या नहीं, फ़ंक्शन Book.helloWorld पर कॉल करें।

धन्यवाद।

उत्तर

9

ठीक है, जहां पूछता है मदद करता है: आप इसे पूछने के मिनट को स्वयं समझ लेंगे। ;)

बस apply(String.to_existing_atom("Elixir.Module"), :helloWorld, []) का उपयोग कर। (शायद नाम "मॉड्यूल" की अनुमति नहीं है, पता नहीं)

+2

छोटे नोट: यदि आप to_existing_atom जब भी संभव हो उपयोग करना चाहिए। परमाणु कचरा इकट्ठा नहीं हैं! –

+0

धन्यवाद! मुझे नहीं पता था कि परमाणु कचरा नहीं एकत्रित हैं। मेरा जवाब संपादित करेंगे। – lschuermann

1

यह भी ध्यान दें कि मॉड्यूल का नाम एक परमाणु है इसलिए String.to_existing_atom करना आमतौर पर आवश्यक नहीं है। इस कोड पर विचार करें:

defmodule T do 
    def first([]), do: nil 
    def first([h|t]), do: h 
end 

इस मामले में आप बस कर सकते हैं इस फैशन में लागू होते हैं:

apply(T,:first,[[1,2,3]]) 
#=> 1 

या इस उदाहरण (नीचे सूची अमृत List मॉड्यूल है):

apply(List,:first,[[1,2,3]]) 
#=> 1 

मेरा कहना है कि यदि आप मॉड्यूल का नाम जानते हैं, तो इसे स्ट्रिंग के रूप में पास करना आवश्यक नहीं है और फिर स्ट्रिंग को मौजूदा परमाणु में परिवर्तित करना आवश्यक है। उद्धरण चिह्नों के बिना बस नाम का उपयोग करें।

+0

हां, यह बिल्कुल सही है।लेकिन मेरे मामले में, मॉड्यूल-नाम गतिशील बनाने का लक्ष्य था। बेशक, यदि आप मॉड्यूल के नाम को जानते हैं, तो यह भी काम करेगा। – lschuermann

6

ध्यान दें कि आपको हमेशा "एलिक्सीर" के साथ अपने मॉड्यूल को उपसर्ग करने की आवश्यकता है।

defmodule Test do 
    def test(text) do 
    IO.puts("#{text}") 
    end 
end 

apply(String.to_existing_atom("Elixir.Test"), :test, ["test"]) 

प्रिंट "परीक्षण" और रिटर्न {: ठीक}

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