Предоставление символов в $ ContextPath - PullRequest
21 голосов
/ 27 октября 2011

Существует множество полезных контекстных функций Internal`, таких как InheritedBlock, Bag и StuffBag и т. Д., А также многие другие. полезные Developer` функции.

Я хочу раскрыть выборку этих символов так, чтобы к ним можно было обращаться просто без имени контекста, но я не хочу раскрывать все их, добавив Internal` и Developer` к $ContextPath.

Я мог бы использовать символ прокси, такой как Bag = Internal`Bag, но это не является ни чистым, ни полностью правильным, так как это ссылка, и, например, атрибуты не наследуются.

Есть ли способ выборочно выставлять нужные мне символы, не прибегая к клуге выше?

Ответы [ 2 ]

11 голосов
/ 05 ноября 2011

Это ИМО очень глубокий и достоверный вопрос, и, судя по подсчетам голосов, я не одинок в своих мыслях.Если бы мы полностью поддерживали эту функцию на уровне языка, это дало бы совершенно новый способ манипулирования областью видимости и инкапсуляцией, и 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];

Затем создайте функцию, которая будет включать ваши любимые ярлыки, например:

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 используется подОбратим внимание, что на самом деле происходит то, что ваши сокращенные символы заменяются полностью определенными именами символов перед выполнением кода.

Это насколько я мог понять, но эта функция, похоже, особенно требует поддержки со стороны языка.

5 голосов
/ 06 ноября 2011

Вариант ответа Леонида, который применяется на более ранней стадии:

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}

Однако, похоже, он работает только в интерфейсе ноутбука, а не при использовании математики в командной строке.

...