首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >向$ContextPath公开符号

向$ContextPath公开符号
EN

Stack Overflow用户
提问于 2011-10-27 15:45:25
回答 2查看 812关注 0票数 23

有各种有用的Internal`上下文函数,如InheritedBlockBag and StuffBag等,以及许多有用的Developer`函数。

我希望公开这些符号的选择,以便可以在没有上下文名称的情况下简单地对它们进行寻址,但我不想通过将Internal`Developer`添加到$ContextPath来公开所有这些符号。

我可以使用像Bag = Internal`Bag这样的代理符号,但这既不干净也不完全正确,因为它是一个引用,例如属性不是继承的。

有没有一种方法可以有选择地公开我想要的符号,而不是求助于上面的kluge?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2011-11-05 09:06:11

这是一个非常深刻和有效的问题,从票数来看,我并不是唯一一个这样想的人。如果我们在语言级别上完全支持此功能,这将为操作作用域和封装提供一种全新的方法,并且IMO通常允许更干净的代码和更好的信息隐藏。这类似于Python语言中的from module-name import name1,name2,...

也许和我们许多人一样,我尝试过多种方法,但所有这些方法似乎都很脆弱和不完整。最坏的情况是包,我没有好的解决方案。对于FrontEnd中的交互式工作,这里有一个可能是可以接受的。首先定义一个通用宏来进行文字替换:

代码语言:javascript
复制
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];

然后,创建一个包含您最喜欢的快捷键的函数,例如:

代码语言:javascript
复制
shortcutF = 
   Function[code,
     withImported[
       {
         {PackedArrayQ, ToPackedArray, FromPackedArray} -> "Developer`",
         {InheritedBlock, WithLocalSettings} -> "Internal`"
       },
       code
     ],
     HoldAll];

现在,您可以将代码包装在shortcutF中,并开始使用短名称。到目前为止,这也适用于包,但您必须将所有代码(或至少包含快捷方式的那些部分)包装在shortcutF中,这不是很方便。为了进一步方便起见,您可以将上述函数赋值给$Pre

代码语言:javascript
复制
$Pre = shortcutF;

以下是一些使用示例:

代码语言:javascript
复制
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

因为With是在幕后使用的,所以实际发生的情况是,在代码执行之前,您的快捷符号会被完全限定的符号名称替换。

这就是我所能得到的,但这个特性似乎特别需要来自语言的本机支持。

票数 12
EN

Stack Overflow用户

发布于 2011-11-06 23:21:52

列昂尼德的答案的一个变体,适用于更早的阶段:

代码语言:javascript
复制
InternalSymbols={"Bag","BagLength","BagPart","StuffBag"}
$PreRead=#/.(InternalSymbols/.{s_String:>s->"Internal`"<>s})&

在笔记本中键入此内容后,请键入

代码语言:javascript
复制
?Bag

给了我

代码语言:javascript
复制
Internal`Bag
Attributes[Internal`Bag]={Protected}

代码语言:javascript
复制
?AbsSquare

给出

代码语言:javascript
复制
Information::notfound: Symbol AbsSquare not found.

代码语言:javascript
复制
?Internal`AbsSquare

给出

代码语言:javascript
复制
Internal`AbsSquare
Attributes[Internal`AbsSquare]={Listable,NumericFunction,Protected}

然而,它似乎只在notebook界面中工作,而不是在命令行上使用数学时。

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/7912984

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档