2011-04-12 28 views
11

मेरे पास कुछ सहायक कार्यों के साथ एक निर्देशिका है जिसे पैकेज में रखा जाना चाहिए। चरण एक स्पष्ट रूप से +mypackage\ जैसे निर्देशिका का नामकरण कर रहा है, इसलिए मैं mypackage.somefunction के साथ फ़ंक्शंस कॉल कर सकता हूं। समस्या यह है कि, कुछ फ़ंक्शंस एक-दूसरे पर निर्भर करते हैं, और स्पष्ट रूप से MATLAB को पैकेज नामों को स्पष्ट रूप से पैकेज नाम बताकर पैकेज को कॉल करने के लिए आवश्यक फ़ंक्शन में फ़ंक्शन फ़ंक्शन की आवश्यकता होती है, इसलिए मुझे सभी फ़ंक्शन कॉल को फिर से लिखना होगा। इससे भी बदतर, क्या मुझे पैकेज का नाम बदलने का फैसला करना चाहिए, सभी फ़ंक्शन कॉल को भी फिर से लिखना होगा। जब मैं के साथ शुरू होता हूं, तो ये फ़ंक्शन निर्देशिका में अब भी सही ढंग से काम नहीं करते हैं जब मैं cd निर्देशिका में करता हूं।एक निर्देशिका में एक पैकेज को बदलने के लिए कैसे?

क्या पुनः लिखने से कोई आसान समाधान है? या भविष्य में पैकेज नामकरण की सुविधा के लिए import this.* जैसे कम से कम कुछ आत्म-संदर्भित?


संपादित मैंने देखा एक ही वर्गों और स्थिर तरीकों के लिए चला जाता है, जिसके कारण मैं this separate question में आत्म निर्देशात्मक हिस्सा डाल दिया।

+0

कॉलिंग * आयात * आपकी फ़ाइल की शुरुआत में नौकरी करना चाहिए। अधिक जानकारी के लिए प्रलेखन [आयात] (http://www.mathworks.de/help/techdoc/ref/import.html) देखें। – zellus

+0

@zellus: धन्यवाद, मैंने पहले से ही कोशिश की है - मुझे पैकेज में _every_ फ़ंक्शन आयात करने के लिए 'आयात mypackage। * 'शामिल करना होगा (आयात फ़ंक्शन वर्कस्पेस में हैं, वैश्विक नहीं), और जब मैं नाम बदलने का निर्णय लेता हूं तो इसे बदलना होगा पैकेज :( –

उत्तर

14

सच में, मुझे नहीं पता कि आपको वास्तव में अपने पैकेजों का नाम बदलना चाहिए। ऐसा लगता है कि package in MATLAB के पीछे पूरा विचार संबंधित कार्यों और वर्गों के एक समूह को एक संग्रह में व्यवस्थित करना है जिसे आप आसानी से नाम टकराव के बारे में चिंता किए बिना "टूलबॉक्स" के रूप में उपयोग या वितरित कर सकते हैं।

इस प्रकार, पैकेजों में कार्यों और कक्षाओं को रखने के लिए अंतिम चरण है जो आप औजारों का एक अच्छा पॉलिश संग्रह बनाने के लिए करते हैं, इसलिए आपके पास वास्तव में अपने पैकेज का नाम बदलने का अधिक कारण नहीं होना चाहिए। इसके अलावा, आपको केवल पैकेज नाम कॉल करने के लिए पैकेज नाम को प्रीपेड करना होगा।

... (मैं क्या बारे में सुझाव देने के लिए कर रहा हूँ एक अच्छा विचार है अगर सोचने के लिए रोक;)) ...

हालांकि, अगर आप वास्तव में के माध्यम से जाने से बचने के लिए चाहते हैं कि आपके पैकेज और अपने फ़ंक्शन कॉल को नए पैकेज नाम से प्रीपेड करें, एक दृष्टिकोण वर्तमान में चल रहे पैकेज फ़ंक्शन के लिए पूर्ण फ़ाइल पथ प्राप्त करने के लिए MFILENAME फ़ंक्शन का उपयोग करना होगा, पैरेंट स्ट्रिंग निर्देशिका को खोजने के लिए पथ स्ट्रिंग को पार्स करें (जो "+ "), फिर पैरेंट पैकेज आयात करने के लिए परिणाम IMPORT फ़ंक्शन पर पास करें। तुम भी एक अलग समारोह packagename (की आवश्यकता होती है कि आप भी समारोह EVALIN का उपयोग करें) में निम्न चरणों का बन सकता था:

function name = packagename 
    callerPath = evalin('caller','mfilename(''fullpath'')'); %# Get full path of 
                  %# calling function 
    name = regexp(callerPath,'\+(\w)+','tokens'); %# Parse the path string to get 
               %# package directories 
    name = strcat([name{:}],...       %# Format the output 
       [repmat({'.'},1,numel(name)-1) {''}]); 
    name = [name{:}]; 
end 

और तुम तो अपने पैकेज कार्यों के बहुत शुरुआत में यह बन सकता था उन्हें स्वचालित रूप से अपने माता पिता शामिल करने के लिए पैकेज नामस्थान:

import([packagename '.*']); 

क्या यह एक अच्छा विचार है? खैर, मुझे यकीन नहीं है कि कम्प्यूटेशनल प्रभाव क्या होंगे यदि आप हर बार कर रहे हैं तो आप एक पैकेज फ़ंक्शन कॉल करते हैं। इसके अलावा, अगर आप संकुल संकुल के भीतर नेस्ट है आप packagename कि इस तरह दिखता है से उत्पादन प्राप्त होगा:

'mainpack.subpack.subsubpack' 

और IMPORT करने के लिए कॉल तत्काल माता पिता पैकेज subsubpack शामिल केवल होगा।यदि आप अन्य मूल पैकेज भी शामिल करना चाहते हैं, तो आपको उपरोक्त स्ट्रिंग से अंतिम पैकेज को अनुक्रमिक रूप से हटा देना होगा और शेष स्ट्रिंग को आयात करना होगा।

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

+0

धन्यवाद, इस तरह का उत्तर मुझे डर लगता है: -7 लेकिन शायद मुझे कुछ गलत अवधारणा मिली: यदि आप एक निर्देशिका में कई कार्यों को लिखा (या प्राप्त किया गया, अधिक सटीक होना) तो आप क्या करेंगे? अब इसे एक पैकेज में बदलना चाहते हैं (या टूलबॉक्स, क्या इससे कोई फर्क पड़ता है?)? या पैकेज नाम से चिपक रहा है और बस प्रत्येक फाइल में 'आयात' का उपयोग करके वास्तव में अच्छा समाधान है? –

+2

@ टोबियास: अगर मैं अंदर था ऐसी स्थिति, मैं पहले पैकेज नाम (जैसे 'मायपैक') पर बसूंगा, फिर बुलेट को काट दूंगा और यह पता लगाने के लिए कि सभी पैकेज कहां एक दूसरे को कॉल करते हैं, सही तरीके से कॉल करने के लिए' mypack.' को प्रीपेड करना ' उन्हें पैकेज में।इस कदम को कुछ निर्भरता औजारों का उपयोग करके आसान बनाया जा सकता है जो आपको बताते हैं कि कौन से फ़ंक्शन कॉल करते हैं या अन्य फ़ंक्शंस कहलाते हैं। [यह SO सवाल] (http://stackoverflow.com/questions/5518200/automatically- जनरेटिंग- ए-diagram-of- कार्यक्षमता- कॉल-in-matlab) कुछ ऐसे विकल्पों के लिंक। – gnovice

+0

धन्यवाद, यह शायद हर काम में 'आयात Mypack। *' जोड़ने से पहले बेहतर है –

3

मैं एक ही प्रश्न के उत्तर की खोज कर रहा हूं और मुझे पता चला है कि निजी फ़ोल्डरों के साथ पैकेज को संयोजित करने से अधिकांश या सभी कोड को बिना संशोधन के उपयोग किया जा सकता है।

आप

+mypackage\intfc1.m 
+mypackage\intfc2.m 
+mypackage\private\foo1.m 
+mypackage\private\foo2.m 
+mypackage\private\foo3.m 
फिर intfc1 से

, foo1, foo2, और foo3 सब किसी भी पैकेज क्वालिफायर या आयात बयान के बिना पहुंचा जा सकता है, और foo1, foo2, और foo3 है भी किसी भी पैकेज के बिना एक दूसरे को कॉल कर सकते हैं कहो योग्यता या आयात विवरण। यदि foo1, foo2, या foo3 को intfc1 या intfc2 पर कॉल करने की आवश्यकता है, तो उसे mypackage.intfc1 या आयात विवरण के रूप में योग्यता की आवश्यकता है।

यदि आपके पास पारस्परिक रूप से परस्पर निर्भर कार्यों का एक बड़ा सेट है और प्रवेश बिंदुओं की एक छोटी संख्या है, तो यह क्वालीफायर या आयात विवरण जोड़ने का बोझ कम कर देता है।

भी आगे जाने के लिए आप निजी कार्यों

+mypackage\foo1.m   <--- new interface layer wraps private foo1 
+mypackage\private\foo1.m <--- original function 

जहां उदाहरण +mypackage\foo1.m के लिए हो सकता है के रूप में एक ही नाम के साथ पैकेज के स्तर पर नया आवरण कार्यों बना सकते हैं,:,

function answer = foo1(some_parameter) 
    answer = foo1(some_parameter); % calls private function, not itself 
end 

इस तरह ऊपर intfc1 उदाहरण के विपरीत, सभी निजी कोड संशोधन के बिना चला सकते हैं। विशेष रूप से पैकेज स्तर पर एक रैपर द्वारा उजागर किए जाने के बावजूद, किसी अन्य फ़ंक्शन को कॉल करते समय पैकेज क्वालीफायर की आवश्यकता नहीं होती है।

इस कॉन्फ़िगरेशन के साथ, पैकेज-स्तर रैपर समेत सभी फ़ंक्शंस पैकेज नाम से अनजान हैं, इसलिए पैकेज का नाम बदलने से फ़ोल्डर का नाम बदलने से कुछ और नहीं है।

+1

दूसरा एक बहुत ही रोचक दृष्टिकोण है, खासकर जब आप अन्य लोगों से कोड लपेट रहे हैं और केवल कुछ कार्यों का उपयोग करना चाहते हैं। साफ! –

+0

कक्षाओं में इस दूसरे दृष्टिकोण को आप कैसे लागू करेंगे? – user1111652

+0

@ वेक्टर 'फिर intfc1, foo1, foo2, और foo3 से सभी किसी भी पैकेज क्वालीफायर या आयात कथन के बिना पहुंच योग्य हैं' वास्तव में सच नहीं है। आपको पैकेज का नाम निर्दिष्ट करना होगा या पैकेज आयात करना होगा। जैसा कि उल्लेख किया गया है [यहां] (http://stackoverflow.com/a/2748740/2625036): 'पैकेज में कार्यों का एक गुच्छा आगे बढ़ने के बारे में एक मुख्य गोचा यह है कि कार्य और कक्षाएं स्वचालित रूप से उस पैकेज को आयात नहीं करती हैं, जिसमें वे रहते हैं। ' – Ali

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