Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

I would like to use ToExpression (or Symbol) within Manipulate. Specifically, when running Manipulate, I want to build variables from strings, convert them to symbols (dynamic ones) and return values. But I guess I am missing something. Possibly very straight forward.

Here's an example:

a2 = 37; (*GLOBAL*)

Manipulate[
Module[{a1 = 1, a2 = 2, a3 = 3, a4 = 4}, 
Column[{text, var, ToExpression[text <> ToString@var],a1}]], {{text, 
"a"}, {"a", "b"}}, {var, 1, 2, 1, ControlType -> SetterBar}]

So I set a global a2 (to visualize the effect), the rest is local and it returns:

Manipulate 1Manipulate 2

If I change to a2, the global value is retrieved in the third line, i.e. 37, see the screenshot on the right.

So I think the contexts are confusing me. In order to solve my problem, here's what I tried then: I created a Dynamic xoutside the Manipulate and well, consistently (to me), I can now use two different sliders to control the variables (both called x) within Manipulate, see here:

Column[{{Slider[Dynamic[x]], Dynamic[x]},
   Manipulate[
      Column[{
       Style["Within Manipulate", Bold], 
         x, Dynamic[x],ToExpression[x], "", 
       Style["Context", Bold], 
         Context[x], Head[x],"", 
       Style["Converting String", Bold], 
         ToExpression["x"], Dynamic@ToExpression["x"], 
         ToExpression["Dynamic[x]", InputForm, Hold], 
         ToExpression["FE`x"], ToExpression["Global`x"], 
         ToExpression["x", InputForm, Dynamic]}], 
   {{x, 2.5}, 2, 3}]}]

resulting in: (note: running command in Mathematica directly returns context FE, whereas it returns FEGlobal` using export)

Manipulate

So, my question is: is there an easy way within Manipulate to go from strings to symbols? (outside Manipulate, it works just as I expect it to)

Thanks in advance!

EDIT

To clarify: when I use a variable directly in Manipualte(such as a1) its (local) value is returned (i.e. 1), if I use ToExpression["a1"] (i.e. from string) it retrieves the global value. And whats confusing: ToExpression[a1] yields local value.

So the question: how to retrieve the local value of a variable in Manipulate when given the "name" (string) of the variable.

share|improve this question
    
@Nasser: I added an edit above, I hope this helps. The slider I use outside Manipulate is just to show that "some" of the x within Manipulate actually depend on that - which is not what I want. Further, I added a2=37as a Global var to visualize what is happening, i.e. where ToExpression["a2"] is referring to –  Pinguin Dirk Feb 2 '13 at 9:41
add comment

1 Answer 1

Actually we do not need Manipulate to look at this issue. Manipulate just confuses things a little. Lets just simplify things more and just use standard Modules

Lets make a global a1 symbol with the value -99. Then create a Module with a local a1 symbol of value 1 then display the value of a1 from applying ToExpression to the string "a1".

We see the same issue. It displays -99 (the global one) and not 1 (the local one) as expected.

a1 = -99;
Module[{a1 = 1, str},
 str = "a" <> ToString@1;
 Grid[{
   {"string for expression is ", str},
   {"ToExpression[a1] = ",   ToExpression[str]},
   {" my local a1 = ", a1}
   }, Alignment -> Left]
 ]

Mathematica graphics

This shows that ToExpression works at the global level.

Replacing Module with With gives the same result

a1 = -99;
With[{a1 = 1},
 str = "a" <> ToString@1;
 Grid[{
   {"string for expression is ", str},
   {"ToExpression[a1] = ",   ToExpression[str]},
   {" my local a1 = ", a1}
   }, Alignment -> Left]
 ]

Mathematica graphics

But using Block makes it finally use the local symbol

a1 = -99;
Block[{a1 = 1},
 str = "a" <> ToString@1;
 Grid[{
   {"string for expression is ", str},
   {"ToExpression[a1] = ",   ToExpression[str]},
   {" my local a1 = ", a1}
   }, Alignment -> Left]
 ]

Mathematica graphics

So, what is the conclusion out of all this? Just do NOT use ToExpression ;)

Actually ToExpression is not even allowed in demos. So I never used it myself. But from the above, you can just assume when it evaluates the expression, it is done in the global context (i.e. it removes any context currently attached to the symbol, leaving it by default in the global context) but an expert in the Mathematica language would know more about this. part. I do not claim to be one.

update Actually, the context of these symbols are still Global, and I think that is why ToExpression does what it does. We can display the context of each symbol and see:

Clear[foo, a1, x];
a1 = -99;
foo[] := Module[{a1 = 1, x},
   str = "a" <> ToString@1;
   Grid[{
     {"string for expression is ", str},
     {"ToExpression[a1] = ",   ToExpression[str]},
     {" my local a1 = ", a1},
     {" context of  a1 = ", Context[a1]},
     {" context of  x = ", Context[x]}
     }, Alignment -> Left]
   ];

Mathematica graphics

Probably the safest way to do what you want is to create explicitly your own Context as in Begin["local"]; ...... ; End[];` as happens in packages. But this is beyond the scope of this.

share|improve this answer
    
Thanks for that answer and your effort, it certainly covers my problem at hand. It is a nice illustration of the difference Modulevs. Block and scoping. But well, I do find it hard to believe that there is another function (apart from ToExpression and Symbol) to convert a string to a var in a local context –  Pinguin Dirk Feb 2 '13 at 10:30
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.