Почему это использование Begin [] не работает?
Если мы будем оценивать эти строки один за другим, x
будет создан в контексте cc
.
Begin["cc`"];
x = 1;
End[]
Однако, если мы их оценим вместе,
(Begin["cc`"];
x = 1;
End[])
то x
будет создано в Global
. Это несмотря на следующую печать cc`
:
(Begin["cc`"];
Print[$Context];
End[])
В чем причина такого поведения? Я предполагаю, что контексты имеют значение только во время фазы анализа, а не для оценки.
Случай использования. Я хотел создать палитру Button
, которая определит некоторые символы, если они еще не существуют, в контексте "private", чтобы избежать конфликта с глобальными. Какой предпочтительный способ сделать это, за исключением размещения всех определений в файле пакета и загрузки их из палитры? (Я хотел бы сохранить палитру автономной.)
Ответы
Ответ 1
Символы (и их контексты) создаются при разборе, а не в оценке. Если мы используем $NewSymbol
, мы можем это увидеть:
$NewSymbol=Print["Name: ",#1," Context: ",#2]&;
Print["first"];
test1;
Print["last"]
(Print["first"];
test2;
Print["last"])
Первый печатает:
first
Name: test1 Context: Global`
last
потому что каждая строка в ячейке рассматривается как отдельный вход. Второй использует круглые скобки, чтобы заставить все три строки считаться одним входом и печатать
Name: test2 Context: Global`
first
last
из которого видно, что test2
был создан в контексте Global`
до того, как произошла какая-либо оценка.
Я думаю, что самый простой способ работать с этим - использовать явный контекст для вашего символа: cc`x = 1
.
Ответ 2
Для вашего второго вопроса, я отсылаю вас к этому моему ответу, который эффективно автоматизирует описанные вами шаги (с помощью функции ParseTimeNameSpaceWrapper
). Возможно, потребуется больше работы, чтобы сделать его более надежным, но это может быть отправной точкой. Я иногда использую этот материал.
Ответ 3
Только для справки:
(Begin["cc`"]; Evaluate[Symbol["x"]] = 1; End[])
cc`x
1