Ответ 1
Это ИМО - очень глубокий и правильный вопрос, и, судя по подсчету голосов, я не одинок в этом. Если бы эта функция полностью поддерживалась на языковом уровне, это дало бы совершенно новый способ манипулировать областью охвата и инкапсуляции, и ИМО часто позволяла бы более чистый код и лучшую информацию скрывать. Это было бы похоже на 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[[email protected]]]
]},
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]:= [email protected][Range[10]]
Out[33]= False
Поскольку With
используется под обложкой, что действительно происходит, так это то, что ваши короткие символы заменяются полностью квалифицированными именами символов, прежде чем код будет выполнен.
Это насколько я могу получить, но эта функция, похоже, особенно плачет за поддержку на родном языке.