2010-11-24 4 views
7

Gelegentlich ich in das folgende Szenario ausführen - ein Verfahren, um eine globale Funktion verwendet f[x] eine Berechnung zu tun, inzwischen ein anderes Verfahren macht f=5 die f[x] in 5[x]Detecting DownValue/OwnValue Konflikte

alle nachfolgenden Anrufe dreht Ich weiß über lokalisierende Variablen, aber ich bevorzuge globale Variablen früh in der Entwicklung.

Ich kann mir keinen legitimen Grund vorstellen, OwnValues ​​und DownValues ​​zu mischen. Gibt es eine Möglichkeit, eine Warnmeldung zu implementieren, wenn eine Situation wie oben auftritt?

Neben Tipps unten können Standardkontext in OptionsInspector unter Zellenoptionen/Evaluation Optionen/CellContext

Antwort

11

Sie können Protect[f] finden verwenden, um weitere Zuordnungen zu vermeiden (jeglicher Art) und Unprotect[f] sie wieder zu ermöglichen.

Sie könnten auch mit up-Werte einige einfache hackery tun Set[f, ...] um zu verhindern, tatsächlich eigene Werte auf f setzen, aber damit immer noch die Zuordnung von Abwärts Werte ohne Protect/Unprotect verwenden:

In[76]:= ClearAll[f] 

In[77]:= f /: Set[f, x_] := x 

In[78]:= f = 7 

Out[78]= 7 

In[79]:= f 

Out[79]= f 

In[80]:= f[x_] := x + 1 

In[81]:= f[1] 

Out[81]= 2 

Das Obige blockiert transparent die Verwendung von Set auf f. eine aktuelle Nachricht Ausstellen ist zu einfach:

In[93]:= f::noov = "Blocked attempt to assign `1` as an OwnValue of f"; 

In[94]:= f /: Set[f, x_] := (Message[f::noov, x]; x) 

In[95]:= f = 7 

During evaluation of In[95]:= f::noov: Blocked attempt to assign 7 as 
    an OwnValue of f 

Out[95]= 7 
+0

Was denken Sie über das Überschreiben der Warnmeldung Set/SetDelayed, wenn der DownValue/OwnValue-Konflikt besteht? –

+1

Wahrscheinlich möglich, aber wahrscheinlich fragil. Haben Sie darüber nachgedacht, stattdessen Kontexte zu verwenden ('Begin' /' End') oder Kontexte auf Zellen-/Notebook-Ebene zu setzen? –

+0

+1, ich hatte nicht gedacht, solche Werte zu verwenden. Klug. Darüber hinaus machen Sie einen guten Punkt über Kontexte auf Zellebene; Ich habe festgestellt, dass sie eine der nützlichsten Verbesserungen seit v. 5 sind. – rcollyer

3

Dies nicht die ursprüngliche Frage beantworten, um eine Warnmeldung zu erzeugen, aber Formal Symbols ist praktisch für die Verwendung als globale Symbole. Sie sind automatisch geschützt und können daher nicht versehentlich neu definiert werden. Sie geben ein formelles Symbol mit den Tastenanschlägen <ESC>$f</ESC> ein, wobei f ein beliebiger Buchstabe sein kann. Der Nachteil ist, dass es vier Tastenanschläge benötigt, um das Symbol anstelle von einem einzugeben.

+0

+1 für den nützlichen Leckerbissen. Ist es möglich, formale Symbole aus doppelgeprägten oder griechischen Buchstaben programmatisch zu generieren (etwa in einem Paket)? Wenn nicht, nehme ich an, dass die MakeBoxes-Beispiele in der Dokumentation zu den Formalsymbolen eine Ersetzung (von Zeichen und/oder Farbe) erlauben würden. Dies könnte ein wirklich nützlicher Designtrick sein. :) – telefunkenvf14

+0

@ telefunkenvf14 Wenn Sie sich auf die unverwechselbare visuelle Erscheinung der formalen Symbole beziehen (mit den Punkten oben und unten), weiß ich keine Möglichkeit, andere solche Symbole zu erzeugen. Soweit ich das beurteilen kann, sind die gepunkteten Buchstaben Zeichen in einer speziellen Schriftart. Man könnte wahrscheinlich mit 'Underoverscript' und' Symbolize' nah genug kommen, aber die Ergebnisse könnten von der Tastatur aus mühsam sein. Die anderen Merkmale von formalen Symbolen, denen es an eingebauten Definitionen fehlt und die durch 'Protect' gesichert sind, sind leicht für jedes andere Symbol zu arrangieren. – WReach