Hot answers tagged contexts
23
Link to the code on GitHub
I have been using this. It's mostly Leonid's code from the stackoverflow question you linked to, but it uses Definition instead of DownValues. Symbol names are printed without any context, but the full symbol name is put into a Tooltip so you can always find out what context a symbol is in.
Update
FullDefinition[symbol] claims ...
22
The answer of @R.M. already explains the essence of the problem. You can streamline the process of removing the Combinatorica from the $ContextPath by loading it via
Block[{$ContextPath}, Needs["Combinatorica`"]]
(or use Get intead of Needs, although Needs is a preferred way to load a package). In this way, you don't have to do anything afterwards, ...
18
The red colouring indicates shadowing — i.e., when a symbol originally in a particular context, is exposed to the current context path, thereby clashing with another symbol of the same name in a different context, also on the context path.
Example of shadowing:
Here is a short example that demonstrates this. Try it out in a fresh kernel (call Quit[] ...
17
Short answer: yes, it is possible.
The problem is that parsing is done line-by-line only for the top-level code. For code inside some head(s), it is first parsed as a whole. Therefore, your f is parsed to Global`f, and this is why that symbol is used. Here is what you can do, schematically:
DynamicModule[{x = 5},
With[{def = MakeBoxes[f[y_] := y^2 + 1;], ...
17
Shadowing occurs only when there are two functions with the same name that are in $ContextPath. So right after you do <<Combinatorica`, do the following:
$ContextPath = Rest@$ContextPath;
What this does is that it removes Combinatorica (which is the package you just loaded). Now the only Graph function that's on the path is System`Graph and you can ...
16
Symbols are created in the current context during parsing. This should not be a problem in normal circumstances as the symbols are merely "initialized" without values or properties.
See these posts for more information:
Is it possible to use Begin and End inside a Manipulate?
Why doesn't this use of Begin[] work?
You raise good questions in the ...
12
I am not sure these are the best ways but they should work.
You could do what you did with Dimensions for all the symbols in Combinatorica`
For example, running this
replaceAndLoad[context_String -> toContext_String] :=
Block[{$ContextPath},
Needs[context];
Scan[ToExpression[
toContext <> StringReplace[#, context ~~ sym__ :> sym] ...
11
One possibility would be to modify the notebook's stylesheet so that Input cells (or a clone) have something like:
CellProlog -> ($ContextPath = DeleteDuplicates[Prepend[$ContextPath,"abc`"]])
Then your package's context should be available to all the code:
10
Your specific problem looks like you somehow managed to not load the package properly (did you evaluate Get[...]?). There's also an excess space in your long-form call to f (just before EndPackage[]) that will give you an error.
Although your package will work if you fix the typo, this is not in general a good way to define your function. To see why, try:
...
10
This question is not too distantly related to my own on StackOverflow:
Exposing Symbols to $ContextPath
Leonid provides an interesting approach there that could be adapted to your problem.
Rojo provides a solution that creates "proxy symbols" but these are not 100% equivalent. Information no longer works correctly for example:
?? Com`KSubsets
This ...
9
I think, using contexts here is a sensible suggestion, particularly because you want to use several variables. One possible alternative is to set up a struct-like data structure, where encapsulation mechanism is based on Module-generated persistent variables. There were many discussions related to emulation of structs in Mathematica, but, given the ...
9
I don't think that Developer` is going to go away; there is too much (also internal) stuff depending on it. What I do at the beginning of a package:
pack = Developer`ToPackedArray;
packedQ = Developer`PackedArrayQ;
then only use those; if anything changes then it's only one place I need to change it. On the other hand a re-factoring: of ...
8
I don't have an access to Mathematica at the moment, so what follows is untested.
What you observed can be understood by looking at the mechanics of package loading and symbols creation. I dealt with this problem before, and will re-post here verbatim my answer from the MathGroup thread:
The setup and the problem
Suppose you have two packages, the main ...
8
I would just use strings, for all their fragility:
ClearAll[print];
print[sym_, {conts_String}] :=
With[{altptrn = Alternatives @@ Reverse[SortBy[{conts}, StringLength]]},
Print@StringReplace[ToString[InputForm@FullDefinition@sym],
(x : (_ | "") ~~ altptrn ~~ y : (_ | "")) /; ! (x === "\"" && y === "\"") :>
...
8
The issue here is that you haven't actually defined myContext`x, just plain old x. It is possible to access global variables within a context (that's exactly what happens when you use built-in function within a package), and that is what you have done.
Clear[fun];
fun[] := Module[{}, Begin["myContext`"];
x = 1;
End[];];
fun[]
This is undefined.
...
6
It seems like the StandardForm (default for output) of Times in any context (or Plus, etc) is with the * and + symbols.
But your assumption isn't wrong I think, the symbols * and + are mapped to System Times and System Plus. Try
PrependTo[$ContextPath, "blo`"];
blo`Times[a_, b_] := 8;
FullForm@MakeExpression[RowBox[{"a", "*", "b"}], StandardForm]
I ...
6
How can you give a Module a context and have its local variables and Modules belong to that context?
Here is an idea:
SetAttributes[account, HoldAll ]
makeAccount[ initBalance_ ] :=
Module[ { balance = initBalance },
account[ balance ]
]
account /: balance[ account[ bal_ ] ] := bal
account /: deposit[ account[ bal_ ], newBal_ ] := ( bal += newBal )
account /: withdraw[ account[ bal_ ], amount_ ] := ( bal -= amount ) /;
amount <= bal
account ...
6
When this is unavoidable, I just refer to full contexts. This happens all the time when using Combinatorica, which defines Graph objects that conflict with V8's new built in Graph object. Here's a sample session (presented as an image to show highlighting and such):
6
This works, though it'd be nicer to have a built-in way to do it:
SetAttributes[fullyQualifiedName, {HoldAll, Listable}];
fullyQualifiedName[a_] := Context[a] <> SymbolName[Unevaluated@a]
Some demonstrations:
In[4]:= fullyQualifiedName[a]
Out[4]= "Global`a"
In[5]:= foo = 3
Out[5]= 3
In[6]:= fullyQualifiedName[foo]
Out[6]= "Global`foo"
In[7]:= ...
6
Here is an alternative:
ClearAll[f];
SetAttributes[f, HoldAll];
f[a_Symbol] :=
Block[{$ContextPath = {"Test`"}, $Context = "Test`"},
ToString[Unevaluated@a]
];
It is based on the way Mathematica treats short and long names depending on the current settings of $Context and $ContextPath. The context "Test`" must not exist for it to be ...
5
How can you give a Module a context and have its local variables and Modules belong to that context?
Here's one approach, although I don't think it will actually meet your needs.
The main thing is that care needs to be taken to make sure symbols are created in the correct context, with context being set during parsing, not evaluation.
moduleState[context_String] :=
With[{init = ToExpression[context <> "init"],
state = ToExpression[context ...
5
See CellContext:
The below dialog box can be found in Format -> Option Inspector or Edit -> Preferences -> Advanced -> Open Option Inspector.
When using custom CellContext you will need to use Global` to access global symbols, for example:
data = RandomReal[NormalDistribution[], 100];
ListPlot[MovingAverage[data, Global`windowLength]]
If you are ...
5
The explanation can be found in the doc to BeginPackage and Begin
BeginPackage["context`"] makes context` and System`the only active contexts.
Begin["context`"] resets the current context.
Therefore, at the moment you first mention the symbol test it is not created it in the Global context. This can be seen from you (simplified) example
...
5
It looks like FeynArts did not get patched. Please follow the instructions here, i.e., reinstall fc820.zip and then do :
$LoadPhi=True;
Needs["HighEnergyPhysics`FeynCalc`"];
If I find time I update FeynCalc to include a patched FeynArts. The problem is that some examples in fcexamples do not work with FeynArts 3.7 and I need to have a look at how to fix ...
4
I have not tested this yet but here is one possible approach:
contextFreeDefinition[sym_Symbol, contexts_List] :=
Internal`InheritedBlock[{sym},
ClearAttributes[sym, ReadProtected];
If[contexts =!= {}, Message[contextFreeDefinition::contexts, contexts]];
Block[{ipf = ToString @ InputForm @ FullDefinition @ sym},
ipf = ...
4
Now, with v9, I can undelete this answer :)
You could set a context dependent on a certain counter value.
Add to your stylesheet, to the "Input" style, the following option
CellContext:>"Section"<>ToString@CurrentValue[{"CounterValue", "Section"}]<>"`"
and in my few tests you get a context dependent on the last section number. It can ...
4
How can you give a Module a context and have its local variables and Modules belong to that context?
If each will have it's own methods, you can't avoid writing every method by hand, and, you can always precede your modules by Begin["objX`"] and end them with End[], which I believe is quite neat... If they have the same methods but different state like your example, you can use what Brett suggested I guess.
Or, if you are just interested in how to ...
4
I wrote something very similar to what you want in this answer. Modifying the core of the answer there to also handle temporary variables from Module, you can do:
str = "MyFunc[ShowIt[Q1`Private`var1$123],ShowIt[Q2`Private`var2$456],0., 1.]";
With[{pat = WordCharacter},
StringReplace[str, (pat ... ~~ "`") .. ~~ s : pat .. ~~ ("$" ~~ NumberString) ...
4
I'm just going to go ahead an rephrase the answer. The problem as Leonid points out is akin to shadowing. Here is a very simple example of the behavoir:
Remove[test`x, x]
(
Begin["test`"];
x = 42;
End[];
{x, test`x}
)
{42,test`x}
Remove[test`x, x]
Begin["test`"];
x = 42;
End[];
{x, test`x}
{x,42}
If you use Trace You will see that in the ...
4
Here is some code that can be a start:
Clear[$maxLevel, packageOrDirQ, pckgname, hasPackagesQ, hasInitFileQ]
$maxLevel = 4;
packageOrDirQ[name_String] :=
DirectoryQ[name] || (
StringMatchQ[name, "*.m"] &&
!StringMatchQ[FileBaseName[name], "init" | "PacletInfo"]);
hasPackagesQ[dir_String?DirectoryQ, level_] :=
...
Only top voted, non community-wiki answers of a minimum length are eligible



