From: Chris Degnen on 31 Mar 2010 06:27 I have some code which reads in rules using variable names that already exist, e.g. a and b. I used Block to achieve the replacement instructions, but was surprised to have to use BeginPackage and Begin again to get the context right. Can anybody comment on what's going on here? BeginPackage["Test`"]; TestFunction::usage = "Testing contexts"; Begin["`Private`"]; TestFunction[] := Module[{}, a = 1; b = 1; BeginPackage["Test`"]; Begin["`Private`"]; Block[{a, b}, x = Get["x.dat"]; a2 = a /. x; b2 = b /. x;]; End[]; EndPackage[]; Return[{a2, b2}]]; End[]; EndPackage[]; x = {a -> "one", b -> "two"}; x >> x.dat; TestFunction[]
From: Albert Retey on 31 Mar 2010 07:51 Am 31.03.2010 12:27, schrieb Chris Degnen: > I have some code which reads in rules using variable names that > already exist, e.g. a and b. I used Block to achieve the replacement > instructions, but was surprised to have to use BeginPackage and Begin > again to get the context right. Can anybody comment on what's going > on here? I think everything behaves as expected. The function definition of TestFunction is made in context "Test`Private`" so the symbols a and b used there are actually Test`Private`a and Test`Private`b. When you use the function, it runs in context Global` , so when you read the file with Get the new symbols are created as Global`a and Global`b so that the patterns in TestFunction don't match. Only if you do set the Context to Test`Private` before reading the file, the symbols a and b will be in the context Test`Private` and the patterns will match. > BeginPackage["Test`"]; > TestFunction::usage = "Testing contexts"; > Begin["`Private`"]; > TestFunction[] := Module[{}, > > a = 1; > b = 1; > > BeginPackage["Test`"]; > Begin["`Private`"]; > > Block[{a, b}, > x = Get["x.dat"]; > a2 = a /. x; > b2 = b /. x;]; > > End[]; > EndPackage[]; > > Return[{a2, b2}]]; > > End[]; > EndPackage[]; > > x = {a -> "one", b -> "two"}; > x >> x.dat; > TestFunction[] > here are some suggestions for your code: a Module with an empty variable list does nothing, so there is no reason to use it. Also the Return at the end is not necessary. Finally I don't see any good reason to use symbols in your replacement rules. If you use strings instead you will avoid any context issues. In some cases this might also be more efficient, after all a symbol is something much more complicated than just a string. The following is basically doing the same thing with much less effort: BeginPackage["Test`"]; TestFunction::usage = "Testing contexts"; Begin["`Private`"]; TestFunction[] := ({"a", "b"} /. Get["x.dat"]); End[]; EndPackage[]; x = {"a" -> "one", "b" -> "two"}; x >> x.dat; TestFunction[]
From: Chris Degnen on 2 Apr 2010 06:21 On 31 Mar, 12:51, Albert Retey <a...(a)gmx-topmail.de> wrote: > ... I don't see any good reason to use symbols in your > replacement rules. If you use strings instead you will avoid > any context issues. In some cases this might also be > more efficient, after all a symbol is something much more > complicated than just a string. The following is basically > doing the same thing with much less effort: > > BeginPackage["Test`"]; > TestFunction::usage = "Testing contexts"; > Begin["`Private`"]; > TestFunction[] := ({"a", "b"} /. Get["x.dat"]); > End[]; > EndPackage[]; > > x = {"a" -> "one", "b" -> "two"}; > x >> x.dat; > TestFunction[] Thanks Albert. Actually, I had to add in a reset (as shown) for the ContextPath since its rearrangement by EndPackage[] was causing some odd problems in my application. It works fine with the reset, but I will probably switch to using strings as you suggested. BeginPackage["Test`"]; TestFunction::usage = "Testing contexts"; Begin["`Private`"]; TestFunction[] := Module[{contextpath}, a = 1; b = 1; contextpath = $ContextPath; BeginPackage["Test`"]; Begin["`Private`"]; Block[{a, b}, x = Get["x.dat"]; a2 = a /. x; b2 = b /. x; ]; End[]; EndPackage[]; $ContextPath = contextpath; {a2, b2}]; End[]; EndPackage[]; x = {a -> "one", b -> "two"}; x >> x.dat; TestFunction[]
|
Pages: 1 Prev: Manipulate[] and ticks --- offset to avoid collision? Next: How to do numerical computations? |