将符号公开给$ ContextPath

Mr.*_*ard 22 symbols wolfram-mathematica contextpath

有多种的Internal`情况下的功能是有用的,如InheritedBlock,BagStuffBag等,以及许多有用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在封面下使用,实际发生的是在执行代码之前,您的快捷符号被完全限定的符号名称替换.

这是我可以得到的,但这个功能似乎特别为该语言的本机支持而哭泣.


cel*_*chk 5

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)

但它似乎只能在笔记本界面中工作,而不是在命令行上使用数学时.