2011-08-23 12 views
5

मैं निम्नलिखित स्थिति है:चमकदार संदेशों को कैसे बंद कर दें (प्रतीक :: shdw)? या कोई अन्य 'अच्छा अभ्यास' सुझाव?

On[t::shdw] 

Message[t::shdw,"t","Foobar","Dork"] 
-> t::shdw: Symbol t appears in multiple contexts Foobar; definitions in context Dork may shadow or be shadowed by other definitions. >> 

Off[t::shdw] 
Message[t::shdw,"t","Foobar","Dork"] 
-> **No Warning** 

<<MASStoolbox` 
-> t::shdw: Symbol t appears in multiple contexts {MASStoolbox`MASS`,Global`}; definitions in context MASStoolbox`MASS` may shadow or be shadowed by other definitions. >> 

कि कैसे हो सकता है? क्या On और Off केवल वर्तमान नोटबुक को प्रभावित करता है और पैकेज लोड करते समय कोई प्रभाव नहीं पड़ता है? यदि हां, तो इस तरह के संदेशों से कैसे छुटकारा पा सकता है? छाया को कैसे रोकना चाहिए?

उत्तर

7

आप क्या मनाया के लिए कारण यह है कि बयान Off[t::shdw] प्रतीक t$ContextPath पर वर्तमान में है कि के लिए एक छाया संदेश अक्षम कर देता है, लेकिन एक और t, एक और पैकेज की लोडिंग के दौरान बनाया के लिए नहीं है। यदि आप इसे देखना नहीं चाहते हैं तो आपको उस दूसरे t के लिए छाया संदेश को अक्षम करना चाहिए। यहां एक उदाहरण दिया गया है:

In[1]:= Off[Test1`a::shdw] 
In[2]:= 
BeginPackage["Test`"] 
a 
EndPackage[] 

Out[2]= Test` 
Out[3]= a 

In[5]:= BeginPackage["Test1`"] 
a 
EndPackage[] 

Out[5]= Test1` 
Out[6]= a 

यहां, कोई संदेश उत्पन्न नहीं हुआ था।

आम तौर पर, हालांकि, मैं छायांकन संदेश को अक्षम नहीं करना चाहता, क्योंकि छायांकन एक गंभीर समस्या है। छायांकन का अर्थ यह है कि वर्तमान में प्रतीक खोज पथ ($ContextPath) पर एक से अधिक संदर्भ हैं, जिसमें समान (संक्षिप्त) नाम वाले प्रतीक हैं। असल में, यदि प्रतीक छायांकित है, और आप इसे अपने संक्षिप्त नाम से संदर्भित करते हैं (यानी, इसके युक्त पैकेज के बिना प्रतीक), आपको कोई गारंटी नहीं है कि उसी छोटे नाम के कई प्रतीकों का वास्तव में उपयोग किया जाएगा। इसलिए, इससे निपटने का सही तरीका पूरी तरह से छायांकन से बचने के लिए है, जो हमेशा सुविधाजनक नहीं होता है, जो हमेशा सुविधाजनक नहीं होता है।

शेडिंग से बचने का सबसे आसान तरीका यह है कि आपको अपने पैकेज के निजी अनुभाग में आवश्यक पैकेज लोड करना है, जो Begin["`Private`"] लाइन के बाद शुरू होता है। आप हमेशा के रूप में Needs[your-package] पर कॉल करके ऐसा करते हैं। इस तरह, लोड किए गए पैकेज का संदर्भ आपके पैकेज के संदर्भ के साथ $ContextPath पर नहीं रहता है। सबसे बुरा मामला तब होता है जब आपको विवादित प्रतीकों के साथ दो पैकेज लोड करने की आवश्यकता होती है। उनमें से एक के लिए एक रैपर पैकेज बनाने का एक तरीका है, जो उसको एक निजी रूप से लोड करेगा और विरोधाभासी प्रतीकों का नाम बदल देगा। हालांकि यह असुविधाजनक हो सकता है, क्योंकि आपको पैकेज में सभी कार्यों का नाम बदलना होगा, यहां तक ​​कि जो लोग संघर्ष नहीं करते हैं।

पहले पैकेज:

BeginPackage["Test`"]; 
g[x_?NumericQ] := x^2; 
EndPackage[]; 

दूसरा पैकेज:

BeginPackage["Test1`"]; 
g[x_?NumericQ] := x^3; 
EndPackage[] 

मुख्य पैकेज:

BeginPackage["Main`"]; 
f::usage = "A test function of a single argument"; 
Begin["`Private`"]; 

Block[{$ContextPath = $ContextPath}, 
    Needs["Test`"]; 
    (* Define first delegate private function *) 
    g1 = Symbol["g"]]; 


Block[{$ContextPath = $ContextPath}, 
    Needs["Test1`"]; 
    (* Define second delegate private function *) 
    g2 = Symbol["g"]; 
]; 

f[x_] := g1[x]*g2[x] 
End[] 
EndPackage[] 

अब, प्रणाली है कि प्रदान की यहाँ एक और अधिक लचीला संस्करण का एक उदाहरण है जानता है कि अपने पैकेज कहां ढूंढें:

In[2]:= Needs["Main`"] 

In[3]:= f[x] 
Out[3]= Test`g[x] Test1`g[x] 

In[4]:= f[2] 
Out[4]= 32 

और हमने उसी सार्वजनिक समारोह के लिए दो विरोधाभासी प्रतीकों का उपयोग किया। Block का उपयोग करके उस कोड को स्थानीयकृत करने के लिए परोसा जाता है जहां g की पहली या दूसरी परिभाषा का उपयोग किया जाता है। ध्यान दें कि इस विधि के साथ कुछ असुविधा है जिसमें हमें रन-टाइम तक पार्सिंग में देरी करने के लिए Symbol["your-symbol-name"] का उपयोग करने की आवश्यकता है।

एक बहुत ही सरल तरीका है कि उनके लंबे नामों से प्रतीकों का संदर्भ लें। उपर्युक्त में, हम केवल Test`g और Test1`g का उपयोग कर सकते हैं और फिर भारी मशीनरी की आवश्यकता नहीं है।यह कुछ हद तक कम लचीला है, क्योंकि आपको कोड में प्रतीक के संदर्भ को "हार्ड-कोड" करना होगा।

+4

+1 मैं बस एक ही जवाब लिख रहा था (लगभग) बिल्कुल एक ही जवाब ... एक टिप्पणी: अगर फैंटोमा वास्तव में सभी छायांकन संदेशों को बंद करना चाहता है, तो उसे 'ऑफ [सामान्य :: shdw] ' – Simon

+0

@ लियोनीड का उपयोग करना चाहिए, मैं कब्र (') अंक से बच निकला। – rcollyer

+0

@rcollyer धन्यवाद! मुझे अंत में यह करना सीखना चाहिए! :) –

0

आप इसे बंद करने के Message ओवरलोड कर सकते हैं:

[email protected]; 
Message[MessageName[s_, "shdw"],___] := Null; 
[email protected]; 

इस कोड को भी एक और अधिक उपयोगी और सही संदेश का उत्सर्जन करता है, और उसे जोर के साथ अपने दावे की पुष्टि करता है:

[email protected]; 
Message[MessageName[s_, "shdw"], 
    rest : PatternSequence[snHeld_, pathsHeld_, newpath_]] := 
    With[{paths = [email protected]}, 
    {memberpaths = Select[$ContextPath, MemberQ[paths, #] &], 
    sn = [email protected]}, 
    [email protected][ 
     "Note: Symbol `` added in context ``, so that it now appears in \ 
multiple contexts: ``. On the context path, it is currently found in: \ 
``. Definitions in the first context of the context path, ``, will \ 
shadow any other definitions."][sn, newpath, paths, memberpaths, 
    [email protected]]; 
    (*symbol name*) 
    Assert[[email protected] === sn]; 

    (*demonstrate that [email protected] 
    memberpaths is the context used for short names*) 
    Assert[[email protected][ 
     "[email protected]`` === [email protected]````" 
     ][sn, [email protected], sn 
     ] 
    ]; 

    (*and not any other context*) 
    [email protected][TrueQ][[email protected][ 
      "[email protected]`` =!= [email protected]````" 
      ][sn, #, sn 
     ] & /@ DeleteCases[paths, [email protected]] 
    ]; 
    ]; 
[email protected]; 

प्रयास करें:

Global`Image 

Note: Symbol Image added in context Global`, so that it now appears in multiple contexts: {Global`, System`}. On the context path, it is currently found in: {System`, Global`}. Definitions in the first context of the context path, System`, will shadow any other definitions.

सी.एफ. https://mathematica.stackexchange.com/questions/43381/result-about-context-is-inconsistent-with-the-description-of-power-programming/119887#119887

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