将符号暴露给 $ContextPath [英] Exposing Symbols to $ContextPath

查看:38
本文介绍了将符号暴露给 $ContextPath的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有各种有用的 Internal` 上下文函数,例如 InheritedBlock, BagStuffBag 等,以及很多有用的Developer`功能.

There are a variety of Internal`context functions that are useful, such as InheritedBlock, Bag and StuffBag, etc., as well as many useful Developer` functions.

我希望公开这些符号的选择,以便在没有上下文名称的情况下可以清楚地处理它们,但我不想通过添加 Internal`Developer 来公开所有这些符号`$ContextPath.

I wish to expose a selection of these symbols such that they may be addressed plainly without the context name, but I do not want to expose all of them by adding Internal` and Developer` to $ContextPath.

我可以使用代理符号,例如 Bag = Internal`Bag 但这既不干净也不完全正确,因为它是一个参考,例如属性不会被继承.

I could use a proxy symbol such as Bag = Internal`Bag but this is neither clean nor fully correct, since it is a reference, and e.g. attributes are not inherited.

有没有办法选择性地暴露我想要的符号,而不用上面的kluge?

Is there a way to selectively expose the symbols I want, without resorting to the kluge above?

推荐答案

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

This is IMO a very deep and valid question, and judging by the vote count, I am not alone in thinking this. If we had this feature fully supported on the language level, this would give one a whole new way to manipulate the scoping and encapsulation, and would IMO often allow for a cleaner code and better information hiding. This would be similar to from module-name import name1,name2,... in Python.

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

Perhaps as many of us, I have tried multiple approaches, but all of them seem fragile and incomplete. The worst case is for packages, for which I have no good solution. For the interactive work in the FrontEnd, here is one which might be acceptable. First define a general macro to make the literal substitutions:

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];

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

Then, create a function which would incorporate your favorite shortcuts, for example:

shortcutF = 
   Function[code,
     withImported[
       {
         {PackedArrayQ, ToPackedArray, FromPackedArray} -> "Developer`",
         {InheritedBlock, WithLocalSettings} -> "Internal`"
       },
       code
     ],
     HoldAll];

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

You can now wrap your code in shortcutF and start using the short names. Up to now, this would also work for packages, but you will have to wrap all your code (or at least those pieces which contain short-cuts) in shortcutF, which is not very convenient. As a further convenience step, you may assign the above function to $Pre:

$Pre = shortcutF;

以下是一些使用示例:

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 是在幕后使用的,真正发生的是在执行代码之前,您的快捷符号被完全限定的符号名称替换.

Since With is used under the cover, what really happens is that your short-cut symbols get substituted by fully-qualified symbol names, before the code is executed.

这是我所能得到的,但这个功能似乎特别需要语言的原生支持.

This is as far as I could get, but this feature seems to be particularly crying for a native support from the language.

这篇关于将符号暴露给 $ContextPath的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆