Le manuel « Écriture d'extensions R » fournit les conseils suivants pour savoir quand utiliser Imports ou Depends:
Les règles générales sont
- Les packages dont seul l'espace de noms est nécessaire pour charger le package à l'aide de la bibliothèque (pkgname) doivent être répertoriés dans le champ 'Imports' et non dans le champ 'Depends'.
- Les packages qui doivent être attachés pour charger correctement le package à l'aide de la bibliothèque (pkgname) doivent être répertoriés dans le champ «Dépend» uniquement.
Quelqu'un peut-il fournir un peu plus de clarté à ce sujet? Comment savoir si mon package n'a besoin que d'espaces de noms chargés par rapport au moment où j'ai besoin d'un package à joindre? Quels sont des exemples des deux? Je pense que le package typique est juste une collection de fonctions qui appellent parfois des fonctions dans d'autres packages (où un peu de travail a déjà été codé). Ce scénario est-il 1 ou 2 ci-dessus?
Éditer
J'ai écrit un article de blog avec une section sur ce sujet spécifique (recherchez «Imports v Depends»). Les visuels le rendent beaucoup plus facile à comprendre.
Réponses:
"Imports"
est plus sûr que"Depends"
(et fait également d'un paquet qui l'utilise un «meilleur citoyen» par rapport aux autres paquets qui l'utilisent"Depends"
).Une
"Depends"
directive tente de garantir qu'une fonction d'un autre package est disponible en attachant l'autre package au chemin de recherche principal (c'est-à-dire à la liste des environnements renvoyés parsearch()
). Cette stratégie peut cependant être contrecarrée si un autre package, chargé plus tard, place une fonction de nom identique plus tôt sur le chemin de recherche. Chambers ( dans SoDA ) utilise l'exemple de la fonction"gam"
, qui se trouve à la fois dans les packagesgam
etmgcv
. Si deux autres packages étaient chargés, l'un d'eux dépendant degam
et l'autre dépendant demgcv
, la fonction trouvée par les appels àgam()
dépendrait de l'ordre dans lequel ces deux packages étaient attachés. Pas bon.Une
"Imports"
directive doit être utilisée pour tout package de support dont les fonctions doivent être placées<imports:packageName>
(recherchées immédiatement après<namespace:packageName>
), au lieu de sur le chemin de recherche normal. Si l'un des packages de l'exemple ci-dessus utilisait le"Imports"
mécanisme (qui requiert égalementimport
ou desimportFrom
directives dans leNAMESPACE
fichier), les choses seraient améliorées de deux manières. (1) Le package prendrait lui-même le contrôle de lamgcv
fonction utilisée. (2) En gardant le chemin de recherche principal dégagé des objets importés, cela ne casserait même pas potentiellement la dépendance de l'autre paquet sur l'autremgcv
fonction.C'est pourquoi l'utilisation d'espaces de noms est une si bonne pratique, pourquoi elle est désormais appliquée par CRAN, et (en particulier) pourquoi l'utilisation
"Imports"
est plus sûre que l'utilisation"Depends"
.Modifié pour ajouter une mise en garde importante:
Il y a une exception malheureusement courante au conseil ci-dessus: si votre paquet repose sur un paquet
A
qui lui-même"Depends"
sur un autre paquetB
, votre paquet devra probablement être attachéA
avec une"Depends
directive.Cela est dû au fait que les fonctions du package
A
ont été écrites dans l'espoir que le packageB
et ses fonctions seraient attachés ausearch()
chemin .Une
"Depends"
directive chargera et attachera le packageA
, à quel pointA
la propre"Depends"
directive du package provoquera, dans une réaction en chaîne, le chargement et l'attachement du packageB
. Les fonctions du packageA
pourront alors trouver les fonctions du packageB
sur lesquelles elles reposent.Une
"Imports"
directive chargera mais n'attachera pas le packageA
et ne chargera ni n'attachera le packageB
. ("Imports"
après tout, s'attend à ce que les auteurs de packages utilisent le mécanisme d'espace de noms, et que ce packageA
utilisera"Imports"
pour pointer vers toutes les fonctionsB
auxquelles il a besoin d'accéder.) Les appels par vos fonctions à toutes les fonctions du packageA
qui reposent sur des fonctions du packageB
seront par conséquent échouer.Les deux seules solutions sont soit:
A
aide d'une"Depends"
directive.A
et demandez-lui de faire un travail plus soigneux de construction de son espace de noms (selon les mots de Martin Morgan dans cette réponse connexe ).la source
Imports
etDepends
wrt et la vérification des exemples dans les.Rd
fichiers sont en effet subtiles et méritent d'être connues.Imports: ggplot2
, pourquoi mon package ne trouve-autoplot
t- il pas la fonction? Attache évidemmentDepends
la bibliothèque de packages deggplot2
et il n'y a donc pas de problème. par exemple j'ai une fonctionautoplot.myFunction()
qui utilise la@import ggplot2
balise et mon paquet aImports: ggplot2
mais j'obtiens une erreur:Error in eval(expr, envir, enclos) : could not find function "autoplot"
quand j'essaye de l'utiliser.Depends
etImports
deDESCRIPTION
, il se demandait vraiment ce que signifie "importer" une fonction (plutôt que "dépendre" d'elle). Puisque cette dernière question est la question à laquelle j'ai tenté de répondre (et - je suppose - ce que la plupart des gens qui recherchent cette réponse veulent savoir), je laisserai la réponse inchangée.Hadley Wickham donne une explication simple ( http://r-pkgs.had.co.nz/namespace.html ):
la source
Chambers dans SfDA dit d'utiliser «Imports» lorsque ce paquet utilise un mécanisme «d'espace de noms» et puisque tous les paquets doivent maintenant les avoir, alors la réponse pourrait maintenant être toujours utiliser «Imports». Dans le passé, les packages auraient pu être chargés sans réellement avoir d'espaces de noms et dans ce cas, vous auriez dû utiliser Depends.
la source
<namespace:packageName>
, dans le cadre de<imports:packageName>
. Aucun autre appel àlibrary()
n'est nécessaire, et R ne vous avertira pas sur la console au moment du chargement du package à moins que leImport
package ed ne puisse être trouvé.Voici une question simple pour vous aider à décider lequel utiliser:
Votre package nécessite-t-il que l' utilisateur final ait un accès direct aux fonctions d'un autre package?
Le seul moment où vous devriez utiliser "Depends" est lorsque votre package est un module complémentaire ou un compagnon d'un autre package, où votre utilisateur final utilisera les fonctions de votre package et du package "Depends" dans leur code. Si votre utilisateur final ne s'interfacera qu'avec vos fonctions et que l'autre package ne fonctionnera que dans les coulisses, utilisez à la place "Importations".
La mise en garde à ceci est que si vous ajoutez un package à 'Imports', comme vous le faites habituellement, votre code devra faire référence aux fonctions de ce package, en utilisant la syntaxe complète de l'espace de noms, par exemple
dplyr::mutate()
, au lieu de simplementmutate()
. Cela rend le code un peu plus difficile à lire, mais c'est un petit prix à payer pour une meilleure hygiène des emballages.la source