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