Лучшее объяснение того, когда использовать импорт/зависимость

В руководстве Написание R-расширений приведено следующее руководство по использованию Импорт или Зависимости:

Общие правила:

  • Пакеты, пространство имен которых требуется только для загрузки пакета с использованием библиотеки (pkgname), должны быть указаны в поле "Импорт", а не в 'Зависит от поля.
  • Пакеты, которые необходимо добавить для успешной загрузки пакета с использованием библиотеки (pkgname), должны быть указаны только в поле "Зависимости".

Может ли кто-нибудь дать немного больше ясности по этому поводу? Как узнать, когда пакет загружен только в пространстве имен, или когда мне нужен пакет для присоединения? Каковы примеры обоих? Я думаю, что типичный пакет - это всего лишь набор функций, которые иногда вызывают функции в других пакетах (где некоторая часть работы уже закодирована). Является ли этот сценарий 1 или 2 выше?

Edit

Я написал сообщение в блоге с разделом по этой конкретной теме (поиск "Импорт v Зависимости" ). Визуальные эффекты намного легче понять.

4b9b3361

"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().

Директива

A "Depends" загрузит и прикрепит пакет A, в котором пакетная директива A "Depends" будет в цепочной реакции заставлять пакет B загружаться и прикрепляться. Функции в пакете A смогут найти функции в пакете B, на которые они полагаются.

Директива "Imports" будет загружать, но не прикреплять пакет A и не будет загружать и не прикреплять пакет B. ("Imports", в конце концов, ожидает, что разработчики пакетов используют механизм пространства имен, а пакет A будет использовать "Imports" для указания на любые функции в B, к которым ему нужен доступ.) Вызовы по вашим функциям к любым функциям пакета A, которые полагаются на функции в пакете B, будут, следовательно, терпеть неудачу.

Единственными двумя решениями являются:

  • Приложите пакет пакета A с помощью директивы "Depends".
  • Лучше в конечном итоге обратиться к сопровождающему пакету A и попросить их сделать более тщательную работу по созданию своего пространства имен (по словам Мартина Моргана в этом связанном ответить).
117
ответ дан 26 дек. '12 в 23:25
источник

Хэдли Уикхэм дает легкое объяснение (http://r-pkgs.had.co.nz/namespace.html):

Листинг пакета в Depends или Imports гарантирует, что его если это необходимо. Основное отличие заключается в том, что где Imports просто загружает пакет, Depends присоединяет его. Других различия. [...]

Если в противном случае нет веской причины, вы всегда должны указывать пакеты в Imports не Depends. Это потому, что хороший пакет самодостаточно и минимизирует изменения в глобальной среде (включая путь поиска). Единственное исключение - если ваш пакет предназначенный для использования в сочетании с другим пакетом. Например, аналоговый пакет построен поверх веганов. Это не полезно без веган, поэтому у него веган в Depends вместо Imports. По аналогии, ggplot2 действительно должен зависеть от масштабов, а не от импорта.

25
ответ дан 12 авг. '15 в 13:23
источник

Камеры в SfDA говорят использовать "Импорт", когда этот пакет использует механизм "пространства имен", и поскольку теперь все пакеты должны иметь их, тогда ответ теперь может всегда использоваться "Импорт". В прошлом пакеты могли быть загружены без фактического пространства имен, и в этом случае вам нужно было бы использовать Depends.

13
ответ дан 26 дек. '12 в 21:53
источник

Вот простой вопрос, который поможет вам решить, что использовать:

Требуется ли вашему пакету конечный пользователь иметь прямой доступ к функциям другого пакета?

  • НЕТ → Импорт (наиболее общий ответ)
  • ДА → Зависит

Единственный раз, когда вы должны использовать "Зависимости", является то, что ваш пакет является дополнением или компаньоном к другому пакету, где ваш конечный пользователь будет использовать функции как вашего пакета, так и пакета "Зависимости" в своем коде. Если ваш конечный пользователь будет только взаимодействовать с вашими функциями, а другой пакет будет работать только за кулисами, тогда используйте вместо него "Импорт".

Предостережение заключается в том, что если вы добавите пакет в "Импорт", как обычно, ваш код должен будет ссылаться на функции из этого пакета, используя полный синтаксис пространства имен, например. dplyr::mutate(), а не просто mutate(). Это делает код немного clunkier, чтобы читать, но его небольшая цена, чтобы заплатить за лучшую гигиеничность упаковки.

1
ответ дан 22 марта '18 в 19:41
источник