所以問題是,test1
在全局變量Global`a
, 來定義,但在由DynamicModule
創建,因此當地的操縱a
定義。這就是acl以他的Hold[a]
爲例。
也許解決這個問題的最簡單的方法是使用With
插入test1
到操作:
Clear[a, b, c]
test1 = {a, b, c};
With[{test1 = test1},
Manipulate[test1, {a, 0, 10, .1}, {b, 0, 10, .1}, {c, 0, 10, .1}]]
這樣的Manipulate
實際上從未看到test1
,所有它認爲是{a,b,c}
它然後繼續正確本地化。雖然如果在運行Manipulate
之前a,b,c
已被賦予一個值,那麼這會遇到問題 - 因此Clear[a,b,c]
命令。
我認爲最佳實踐是使操作中的所有局部變量完全顯式化。所以你應該做點像
Clear[a, b, c, test1]
test1[a_, b_, c_] := {a, b, c};
Manipulate[test1[a, b, c], {a, 0, 10, .1}, {b, 0, 10, .1}, {c, 0, 10, .1}]
這樣可以避免你所遇到的全局變量和局部變量的問題。當你必須重新閱讀你自己的代碼時,它也使你更容易。
編輯回答在評論這個問題:「我真的想了解爲什麼評估不符合有些嵌套ListPlot工作嗎?」。 IANLS(我不是Leonid Shifrin),所以我不會有一個完美的數學在我的大腦運行(non)standard評價序列,但我會試着解釋這是怎麼回事。
好吧,所以不像Plot
,ListPlot
不需要本地化任何變量,所以它沒有Attribute
HoldAll
。
讓我們定義類似的例子東西:
ClearAll[a, test]
test = {a, a + 1};
你給我的最後一個例子就像
Manipulate[Evaluate[ListPlot[test]], {a, 0, 1}]
通過查看Trace
,你看,這首先計算的第一個參數這是ListPlot[test] ~> ListPlot[{a,a+1}]
並且因爲a
尚未本地化,它會生成一個空的列表圖。看到這一點,只需運行
ListPlot[{a, a + 1}]//InputForm
得到空圖形對象
Graphics[{}, {AspectRatio -> GoldenRatio^(-1), Axes -> True, AxesOrigin -> {0, 0}, PlotRange -> {{0., 0.}, {0., 0.}}, PlotRangeClipping -> True, PlotRangePadding -> {Scaled[0.02], Scaled[0.02]}}]
由於a
已經拋出的象徵價值,他們無法獲得由Manipulate
本地化,所以沒有事情發生太大。
這可以通過仍然評估第一個參數來修復,但不要求ListPlot
,直到Manipulate
已經對變量進行了本地化。例如,下面的兩個工作
Manipulate[Evaluate[listPlot[test]], {a, 0, 1}] /. listPlot -> ListPlot
Manipulate[Evaluate[Hold[ListPlot][test]], {a, 0, 1}] // ReleaseHold
是ListPlot
扔掉,甚至沒有半點怨言非數值的事實,可能是一個功能,但可能會導致一些煩人很難跟蹤的錯誤(如一個這個問題屬於)。也許一個更一致的(但不太有用的?)行爲將返回一個未評估的ListPlot
,如果繪圖值是非數字的......或至少發出警告,指出一些非數字點已被丟棄。
倒數第二個例子你給的是(更多?)有趣的,它看起來像
Manipulate[ListPlot[Evaluate[test]], {a, 0, 1}]
現在,因爲Manipulate
具有屬性HoldAll
,它做的第一件事是包裹論據Hold
,所以如果你看一下Trace
,你會看到Hold[ListPlot[Evaluate[test]]]
被隨身攜帶。 Evaluate
未看到,因爲如Possible Issues部分中所述,「評估僅在第一級上工作,直接在保留函數內」。這意味着test
直到變量已被本地化之後纔會被評估,因此它們被認爲是全局的a
而不是本地的(DynamicModule
)a
。
這是值得我們思考的以下變化是如何工作的
ClearAll[a, test, f, g]
SetAttributes[g, HoldAll];
test = {a, a + 1};
Grid[{
{Manipulate[test, {a, 0, 1}], Manipulate[Evaluate[test], {a, 0, 1}]},
{Manipulate[f[test], {a, 0, 1}],
Manipulate[f[Evaluate[test]], {a, 0, 1}]},
{Manipulate[g[test], {a, 0, 1}],
Manipulate[g[Evaluate[test]], {a, 0, 1}]}
}]
非常類似的問題:更新操縱圖參數變化時(http://stackoverflow.com/q/7126532/211232 ) – WReach