I'm confused about the best approach to localizing symbols used in a Manipulate
. I understand that Manipulate
does a good job by default of localizing symbols defined in its list of controls (even if these are custom controls). But it appears that symbols defined in the first argument, or those initialized with an Initialization
option, are not localized. For example, in the following, z
, r
, and q
(and naturally x
) are local, but y
and t
are not:
Manipulate[
y = 4*x;
Plot[y*x^z+t[q], {x, 0, r}],
{z, 0, 5},
Row[{Control@{{r,2}, 2, Dynamic@q}}],
{{q,10}, 5, 20},
Initialization:> (t[i_]:=5*i)
]
Wrapping the whole Manipulate
in a Model[{y,t}, ...
seems to work, but marks y
and t
in the Manipulate
in red (on macOS) which leaves me wondering if it's the right thing to do.
There are two approaches that seem to work partially, but not altogether:
DynamicModule
Wrapping in DynamicModule
works to localize any symbols not localized by Manipulate
DynamicModule[{y,t},
Manipulate[
y = 4*x;
Plot[y*x^z+t[q], {x, 0, r}],
{z, 0,5},
Row[{Control@{{r,2}, 2, Dynamic@q}}],
{{q,10}, 5, 20},
Initialization:> (t[i_]:=5*i)
]]
but this places y
and t
in an outer scope, which seems the wrong way to proceed.
ControlType -> None
For some symbols, the form {sym, None}
works to localize sym
, but only it seems for limited cases. For example
Manipulate[
y = 4*x;
Plot[y*x^z+t[q], {x, 0, r}],
{z, 0, 5},
Row[{Control@{{r,2},2,Dynamic@q}}],
{{q,10}, 5,20},
{y, None},
Initialization:> (t[i_]:=5*i)
]
localizes y
. But similar attempts to localize a function such as t
fail.
What is the correct approach to localizing symbols inside Manipulate
? Is there are reason to prefer DynamicModule
over ControlType -> None
in general, or vice versa? How should local functions be localized (esp. if the natural thing to be ding is specifying them in Initialization
)?
Additionally, controls defined with Control@
don't highlight the associated symbols to indicate localization, which makes it very hard to read through code and understand how things are scoped. DynamicModule
can be used to fix this (and even leaves the symbol in the inner Manipulate
scope).
Manipulate
only localizes control variables. If you want more localization seeDynamicModule
. SinceManipulate
is a front-end thing (it's a cousin ofDynamic
) you'll want the front-end version ofModule
--i.e.DynamicModule
. In factManipluate
resolves to aDynamicModule
when viewed. $\endgroup$r
, you can add{{r, 2}, None}
after{{q, 10}, 5, t}
. $\endgroup$