23

、、などの便利なさまざまなInternal`コンテキスト関数と、多くの便利な関数があります。InheritedBlockBagStuffBagDeveloper`

これらのシンボルの選択を公開して、コンテキスト名なしでわかりやすくアドレス指定できるようにしたいのですが、とを追加してすべてを公開したくありInternal`ませDeveloper`$ContextPath

次のようなプロキシシンボルを使用できますBag = Internal`Bagが、これは参照であり、たとえば属性が継承されないため、これはクリーンでも完全に正しいものでもありません。

上記のクルーゲに頼らずに、必要なシンボルを選択的に公開する方法はありますか?

4

2 に答える 2

12

これはIMOの非常に深く有効な質問であり、投票数から判断すると、これを考えているのは私だけではありません。この機能が言語レベルで完全にサポートされている場合、これにより、スコープとカプセル化を操作するまったく新しい方法が提供され、IMOにより、よりクリーンなコードとより優れた情報隠蔽が可能になることがよくあります。from module-name import name1,name2,...これはPythonの場合と似ています。

おそらく私たちの多くと同じように、私は複数のアプローチを試しましたが、それらはすべて壊れやすく不完全なようです。最悪のケースはパッケージの場合で、私には良い解決策がありません。フロントエンドでのインタラクティブな作業については、これが許容できる可能性のあるものです。まず、一般的なマクロを定義して、文字通りの置換を行います。

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

次に、お気に入りのショートカットを組み込む関数を作成します。次に例を示します。

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

これで、コードをラップshortcutFして、短い名前の使用を開始できます。これまでは、これはパッケージでも機能しますが、すべてのコード(または少なくともショートカットを含む部分)をでラップする必要がありshortcutF、これはあまり便利ではありません。さらに便利な手順として、上記の関数を$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で使用されているため、実際に発生するのは、コードが実行される前に、ショートカットシンボルが完全修飾シンボル名に置き換えられることです。

これは私が得ることができる限りですが、この機能は言語からのネイティブサポートを特に求めているようです。

于 2011-11-05T01:06:11.110 に答える
5

初期の段階に適用されるしし座流星群の答えのバリエーション:

InternalSymbols={"Bag","BagLength","BagPart","StuffBag"}
$PreRead=#/.(InternalSymbols/.{s_String:>s->"Internal`"<>s})&

これをノートブックに入力した後、次のように入力します

?Bag

私にくれます

Internal`Bag
Attributes[Internal`Bag]={Protected}

その間

?AbsSquare

与える

Information::notfound: Symbol AbsSquare not found.

しかし

?Internal`AbsSquare

与える

Internal`AbsSquare
Attributes[Internal`AbsSquare]={Listable,NumericFunction,Protected}

ただし、コマンドラインで数学を使用する場合ではなく、ノートブックインターフェイスでのみ機能するようです。

于 2011-11-06T15:21:52.407 に答える