Mr.*_*ard 22 symbols wolfram-mathematica contextpath
有多种的Internal`情况下的功能是有用的,如InheritedBlock,Bag和StuffBag等,以及许多有用Developer`的功能.
我希望公开这些符号的选择,以便可以在没有上下文名称的情况下明确地解决它们,但我不想通过添加Internal`和Developer`来公开所有这些符号$ContextPath.
我可以使用代理符号,Bag = Internal`Bag但这既不干净也不完全正确,因为它是一个引用,例如属性不会被继承.
有没有办法有选择地暴露我想要的符号,而不是诉诸上面的kluge?
Leo*_*rin 11
这是IMO一个非常深刻而有效的问题,从投票数来看,我并不是唯一一个想到这一点的人.如果我们在语言级别上完全支持此功能,这将为操作范围和封装提供一种全新的方式,并且IMO通常会允许更清晰的代码和更好的信息隐藏.这与from module-name import name1,name2,...Python 类似.
也许和我们一样,我尝试了多种方法,但所有方法都显得脆弱且不完整.最糟糕的情况是包装,我没有很好的解决方案.对于FrontEnd中的交互式工作,这是一个可以接受的工作.首先定义一个通用宏来进行文字替换:
ClearAll[withImported];
SetAttributes[withImported, HoldAll];
withImported[importingRules : {(_Symbol -> _String) ..}, code_] :=
With @@ Join[
Hold[importingRules] /.
(name_Symbol -> context_String) :>
With[{eval =
Block[{$ContextPath = Append[$ContextPath, context]},
ToExpression[context <> ToString[Unevaluated@name]]
]},
Set[name, eval] /; True],
Hold[code]];
withImported[importingRules : {({__Symbol} -> _String) ..}, code_] :=
Reverse[Hold @@ Flatten[Unevaluated[importingRules] /.
({syms__Symbol} -> s_String) :> Thread[s :> {syms}]], {2}] /.
RuleDelayed -> Rule /.
Hold[expandedRules : ((_Symbol -> _String) ..)] :>
withImported[{expandedRules}, code];
Run Code Online (Sandbox Code Playgroud)
然后,创建一个包含您喜欢的快捷方式的函数,例如:
shortcutF =
Function[code,
withImported[
{
{PackedArrayQ, ToPackedArray, FromPackedArray} -> "Developer`",
{InheritedBlock, WithLocalSettings} -> "Internal`"
},
code
],
HoldAll];
Run Code Online (Sandbox Code Playgroud)
您现在可以将代码包装起来shortcutF并开始使用短名称.到目前为止,这也适用于包,但你必须包装所有代码(或至少包含那些包含快捷方式的部分)shortcutF,这不是很方便.作为进一步的便利步骤,您可以将以上功能分配给$Pre:
$Pre = shortcutF;
Run Code Online (Sandbox Code Playgroud)
以下是一些使用示例:
In[31]:=
WithLocalSettings[Null,Abort[],Print["Cleanup"]]
During evaluation of In[31]:= Cleanup
Out[31]= $Aborted[]
In[32]:= PackedArrayQ[Range[10]]
Out[32]= True
In[33]:= PackedArrayQ@FromPackedArray[Range[10]]
Out[33]= False
Run Code Online (Sandbox Code Playgroud)
由于With在封面下使用,实际发生的是在执行代码之前,您的快捷符号被完全限定的符号名称替换.
这是我可以得到的,但这个功能似乎特别为该语言的本机支持而哭泣.
Leonid的答案的变体适用于早期阶段:
InternalSymbols={"Bag","BagLength","BagPart","StuffBag"}
$PreRead=#/.(InternalSymbols/.{s_String:>s->"Internal`"<>s})&
Run Code Online (Sandbox Code Playgroud)
在笔记本中键入后,键入
?Bag
Run Code Online (Sandbox Code Playgroud)
给我
Internal`Bag
Attributes[Internal`Bag]={Protected}
Run Code Online (Sandbox Code Playgroud)
而
?AbsSquare
Run Code Online (Sandbox Code Playgroud)
给
Information::notfound: Symbol AbsSquare not found.
Run Code Online (Sandbox Code Playgroud)
但
?Internal`AbsSquare
Run Code Online (Sandbox Code Playgroud)
给
Internal`AbsSquare
Attributes[Internal`AbsSquare]={Listable,NumericFunction,Protected}
Run Code Online (Sandbox Code Playgroud)
但它似乎只能在笔记本界面中工作,而不是在命令行上使用数学时.