Update
Kuba and Holistic pointed out some issues with the original answer. This new version addresses those issues:
To insert the built variable names in such a way that they're not affected by previous values, we need to use the three argument form of ToExpression
to wrap the resulting expression in Inactive
. After inserting them into DynamicModule
, we can Activate
the whole thing again.
With[
{vars = Table[
ToExpression["a" <> ToString@i, InputForm, Inactive], {i, 5}]},
ReleaseHold@Activate@Hold@DynamicModule[
vars,
{Slider[Dynamic[#]] & /@ vars,
Slider[Dynamic[#]] &@vars[[1]],
Slider[Dynamic[Evaluate@vars[[1]]]],
Dynamic /@ vars,
Dynamic@vars[[1]],
Dynamic@a1}
]
]
The code above also demonstrates two ways how to solve the issue encountered by Holistic: Slider@Dynamic@vars[[1]]
does not work as expected. The reason for this is once again a Hold...
attribute (HoldFirst
of Dynamic
in this case). To get vars[[i]]
to evaluate before getting wrapped by Dynamic
, we can either call Evaluate
or simply make a pure function and apply that to vars[[1]]
.
Old way
One way to achieve what you're after is to generate the list of variables before and insert them into DynamicModule
using With
:
With[
{vars = Table[ToExpression["a" <> ToString@i], {i, 5}]},
DynamicModule[
vars,
{
Slider[Dynamic[#]] & /@ vars,
Dynamic /@ vars
}
]
]
The problem with your approach arises due to the following two properties of DynamicModule
: It has attribute HoldAll
and it localized the variables. Combined, this means that DynamicModule
doesn't see the variables at the time of first evaluation, resulting in them not being localized.
(You could also try to simply put an Evaluate
around the variable declaration to at least get valid symbols to localize, but you'll run into other issues depending on how you use your variables later.)