Подтвердить что ты не робот

Загрузите пакет математики изнутри пакета

У меня более или менее следующая настройка. В ~/path/to/my/packages у меня есть два пакета package1.m и package2.m. Каждый контур пакета представляет собой, например, следующее:

BeginPackage["package1`"]
[email protected]@Names["package1`*"];
[email protected]@Names["package1`*"];

Begin["`Private`"]

vecNorm[vec_?VectorQ]:=Module[{},Return[Sqrt[vec.vec]]];

End[]
[email protected]@Names["package1`*"];
EndPackage[]

Теперь моя проблема в том, что я хочу использовать vecNorm, определенный в package1.m в package2.m. Как я могу загрузить (безопасно) package1 из package2?

В настоящий момент я загружаю вручную оба пакета следующим образом:

SetDirectory[StringJoin[NotebookDirectory[], "packages"]];
Needs["package1`"]
Needs["package2`"]

из записной книжки, сохраненной в ~/path/to/my. Я хочу загрузить только вручную package2, который, в свою очередь, будет загружаться автоматически и безопасно package1. В общем, я хочу решение, которое изменяет как можно меньше путей и т.д. Математики. Какая должна быть лучшая практика для этого?

PS: В безопасности я подразумеваю, что в будущем, когда я определю package3, который будет использовать vecNorm, а также будет загружаться package1, и никаких конфликтов не произойдет.

4b9b3361

Ответ 1

Существует два рекомендуемых способа загрузки пакета. Один из них - так называемый публичный импорт, и в вашей настройке он будет выполнен как

BeginPackage["package2`",{"package1`"}]

(* Usage messages etc *) 

Begin["`Private`"]

(* code here *)

End[]
EndPackage[]

Здесь вы указываете имя контекста пакета, который хотите загрузить, в списке, который является вторым необязательным аргументом для BeginPackage. Этот способ импорта называется public, потому что загруженный пакет останется на $ContextPath после загрузки основного пакета и, таким образом, будет общедоступным.

Второй метод называется частным импортом и схематически выполняется как

BeginPackage["package2`"]

(* Usage messages etc *) 

Begin["`Private`"]
Needs["package1`"]

(* code here *)

End[]
EndPackage[]

В этом методе загруженный второй пакет будет доступен только для пакета, который загружает его (с помощью Needs), таким образом, частный импорт.

Какой путь вам нужен, будет зависеть от ситуации. Я стараюсь сделать все свои импорт частным, если я не должен сделать их общедоступными. Однако для отладки может быть полезно сначала сделать публичный импорт, так как тогда вы можете играть со вторым пакетом непосредственно на верхнем уровне.

Что касается безопасности, вы можете загрузить пакет любым количеством пакетов, и это будет безопасно. Когда вы одновременно загружаете несколько пакетов в один и тот же контекст, это будет безопасно, если эти пакеты не имеют общедоступных символов с таким же коротким именем. В противном случае вы столкнетесь с тем, что называется проблемой затенения, но лучше всего сделать все необходимое, чтобы избежать этого (это всегда возможно).