Nas*_*ser 1 wolfram-mathematica
我正在使用Leonid的宏方法(见这里)来帮助我管理控制变量的布局Manipulate.
但我发现从宏中,我无法使用其他地方定义的另一个宏.所以我想知道是否有办法在另一个宏中使用宏?
为了解释这个问题,我将首先使用一个级别的宏显示一个非常简单的Manipulate,然后我将通过尝试使用另一个宏中的宏来显示问题.
Manipulate[Text["ok"],
Evaluate@With[{
x = Function[{}, (*----> macro x *)
TabView[{
"x" -> "working on x"
}], HoldAll
],
y = Function[{}, (*----> macro y *)
TabView[{
"y" -> "working on y"
}], HoldAll
]
},(*WITH*)
(* now use the above macros *)
Grid[{
{SetterBar[Dynamic[choice], {1, 2}]},
{Dynamic[Which[choice == 1, x[], choice == 2, y[]] ]}
}]
],
{{choice, 1}, None},
ContentSize -> 300
]
Run Code Online (Sandbox Code Playgroud)

现在为复选框添加一个宏,然后尝试从上面的'x'宏中使用它:
操纵[文字[ "确定"],
Evaluate@With[{
checkBox = Function[{}, Checkbox[Dynamic[c]], HoldAll],
x = Function[{},
TabView[{
"x" -> checkBox[] (*=====> DOES NOT WORK, did not bind *)
}], HoldAll
],
y = Function[{},
TabView[{
"y" -> "working on y"
}], HoldAll
]
},(*WITH*)
Grid[{
{SetterBar[Dynamic[choice], {1, 2}]},
{Dynamic[Which[choice == 1, x[], choice == 2, y[]] ]}
}]
],
{{choice, 1}, None},
{{c, True}, None},
ContentSize -> 300
]
Run Code Online (Sandbox Code Playgroud)
我们认为它不起作用.'x'宏没有'看到'复选框宏.

但是如果我直接在'x'宏中添加复选框的代码,它当然会起作用:
Manipulate[Text["ok"],
Evaluate@With[{
x = Function[{},
TabView[{
"x" -> Checkbox[Dynamic[c]] (* add the definition directly *)
}], HoldAll
],
y = Function[{},
TabView[{
"y" -> "working on y"
}], HoldAll
]
},(*WITH*)
Grid[{
{SetterBar[Dynamic[choice], {1, 2}]},
{Dynamic[Which[choice == 1, x[], choice == 2, y[]] ]}
}]
],
{{choice, 1}, None},
{{c, True}, None},
ContentSize -> 300
]
Run Code Online (Sandbox Code Playgroud)

所以,问题是:是否可以在'x'宏内使用上面的复选框宏?
为了使它更容易,我不会将任何参数传递给宏.我只是使用一个宏作为一个较大的代码片段(控制变量定义)的"简写"名称,如上所示.
这只是为了让我更容易通过仅移动宏名称来布局UI,而不是移动宏定义的更大的代码片段.由于Manipulate没有GUI构建器,因此当需要管理大量控件时,此方法会有所帮助.
这是因为With在这种情况下你需要嵌套.您不能在同一个声明列表中使用另一个变量的声明With.以下是您问题的简化版本:
In[3]:= With[{a=b,c=f[a]},g[c]]
Out[3]= g[f[a]]
Run Code Online (Sandbox Code Playgroud)
这就是你需要的:
In[5]:=
With[{a=b},
With[{c=f[a]},g[c]]]
Out[5]= g[f[b]]
Run Code Online (Sandbox Code Playgroud)
在你的情况下,checkBox发挥作用a,并x发挥作用c.
关于如何制作一个版本的主题With将允许这样的连续绑定,在Mathgroup上和SO处讨论过几次.这是我实现这种构建的:
ClearAll[LetL];
SetAttributes[LetL, HoldAll];
LetL /: Verbatim[SetDelayed][lhs_, rhs : HoldPattern[LetL[{__}, _]]] :=
Block[{With}, Attributes[With] = {HoldAll};
lhs := Evaluate[rhs]];
LetL[{}, expr_] := expr;
LetL[{head_}, expr_] := With[{head}, expr];
LetL[{head_, tail__}, expr_] :=
Block[{With}, Attributes[With] = {HoldAll};
With[{head}, Evaluate[LetL[{tail}, expr]]]];
Run Code Online (Sandbox Code Playgroud)
如果你愿意使用它,你需要做的是改变With对LetL你的代码.
| 归档时间: |
|
| 查看次数: |
453 次 |
| 最近记录: |