"Imports"
безопаснее, чем "Depends"
(а также делает пакет, использующий его, «лучшим гражданином» по сравнению с другими пакетами, которые используют "Depends"
).
Директива
A "Depends"
пытается обеспечить доступность функции из другого пакета, присоединяя другой пакет к основному пути поиска (т. Е. К списку сред, возвращаемых search()
). Эта стратегия, однако, может быть сорвана, если другой пакет, загруженный позже, поместит функцию с одинаковым именем ранее в путь поиска. Chambers ( в SoDA ) использует пример функции "gam"
, которая находится в пакетах gam
и mgcv
. Если были загружены два других пакета, один из которых зависит от gam
, а другой - от mgcv
, функция, найденная при вызове gam()
, будет зависеть от порядка, в котором они были присоединены к этим двум пакетам. Не хорошо.
Директива "Imports"
помещает импортированный пакет в <imports:packageName>
(поиск производится сразу после <namespace:packageName>
) вместо обычного пути поиска. Если бы один из пакетов в вышеприведенном примере использовал механизм "Imports"
, ситуация могла бы быть улучшена двумя способами. (1) Сам пакет получит контроль над тем, какая функция mgcv
используется. (2) Если очистить основной путь поиска от импортированных объектов, он даже не нарушит зависимость другого пакета от другой функции mgcv
.
Вот почему использование пространств имен является такой хорошей практикой, почему оно теперь применяется CRAN, и (в частности) почему использование "Imports"
безопаснее, чем использование "Depends"
.
Отредактировано для добавления важного предупреждения:
Существует, к сожалению, одно распространенное исключение из приведенного выше совета: если ваш пакет зависит от пакета A
, который сам "Depends"
от другого пакета B
, ваш пакет, вероятно, потребуется прикрепить A
с директивой "Depends
.
Это потому, что функции в пакете A
были написаны с ожиданием, что пакет B
и его функции будут присоединены к search()
пути .
Директива "Depends"
загрузит и присоединит пакет A
, после чего собственная директива A
пакета в цепной реакции вызовет загрузку и присоединение пакета B
. , Функции в пакете A
смогут найти функции в пакете B
, на которые они полагаются.
Директива "Imports"
загрузит, но не присоединит пакет A
и не загрузит или не прикрепит пакет B
. ("Imports"
, в конце концов, ожидает, что разработчики пакетов используют механизм пространства имен, и этот пакет A
будет использовать "Imports"
для указания на любые функции в B
, к которым ему нужен доступ.) Вызовы вашими функциями к любым функциям в пакете A
, которые полагаются на функции в пакете B
, следовательно, потерпит неудачу.
Есть только два решения:
- Приложите пакет
A
, используя директиву "Depends"
.
- Лучше в долгосрочной перспективе, свяжитесь с сопровождающим пакета
A
и попросите их более тщательно поработать над построением их пространства имен (по словам Мартина Моргана в этот связанный ответ ).