Version courte
Pour ceux qui ne veulent pas lire à travers mon "cas", c'est l'essence même:
- Quelle est la méthode recommandée pour minimiser les chances des nouveaux paquets à casser le code existant, c'est à dire de rendre le code que vous écrivez aussi robuste que possible?
-
Quelle est la meilleure façon de faire le meilleur usage de l' espace de noms mécanisme lorsque
a) tout en utilisant contribué paquets (mot à dire dans seulement quelques-R Analyse de Projet)?
b) à l'égard de l'élaboration propres paquets?
La meilleure façon d'éviter les conflits à l'égard des classes formelles (principalement des Classes de Référence dans mon cas) car il n'y a même pas un mécanisme d'espace de noms comparables à
::
pour les classes (AFAIU)?
La façon dont le R univers fonctionne
C'est quelque chose qui a été lancinante dans le dos de mon esprit pendant près de deux ans maintenant, mais je ne me sens pas comme si je suis arrivé à une solution satisfaisante. En Plus je sens qu'il est en train d'empirer.
Nous voyons un nombre toujours croissant de paquets sur CRAN, github, R-Forge et similaires, ce qui est tout simplement formidable.
Dans un tel environnement décentralisé, il est naturel que le code de base qui permet de R (disons que c'est la base de R et a contribué R, pour des raisons de simplicité) va s'écarter de l'idéal de l'état à l'égard de la robustesse: les gens suivent les différentes conventions, il n'y a S3, S4, S4 Classes de Référence, etc. Les choses ne peuvent pas être "aligné", comme ils le seraient si il y avait une "centrale de compensation de l'instance" qui a appliqué les conventions. Ce n'est pas grave.
Le problème
Compte tenu de ce qui précède, il peut être très difficile à utiliser R pour écrire du code robuste. Pas tout ce que vous devez être à la base de R. Pour certains projets, vous finirez chargement assez peu contribué paquets.
À mon humble avis, la question la plus importante à cet égard est la façon dont le concept d'espace de noms est mis à profit dans R: R permet simplement d'écrire le nom d'une fonction/méthode, sans explicitement le nécessitant de l'espace de noms (c - foo
vs namespace::foo
).
Donc, par souci de simplicité, c'est ce que tout le monde est en train de faire. Mais de cette façon, les collisions de noms, de code cassé et la nécessité de réécrire/restructurer le code sont juste une question de temps (ou du nombre de forfaits).
Au mieux, vous savez au sujet de laquelle les fonctions sont masqués/surchargé par un nouveau paquet. Au pire, vous n'avez aucune idée jusqu'à ce que votre code de pauses.
Quelques exemples:
- essayez de charger RMySQL et RSQLite dans le même temps, ils ne vont pas très bien
- aussi RMongo va remplacer certaines fonctions de RMySQL
- prévisions masques beaucoup de choses à l'égard de ARIMA fonctions liées à la
-
R. utils même des masques à l'
base::parse
de routine
(Je ne me souviens pas les fonctions qui, en particulier, ont été à l'origine des problèmes, mais je suis prêt à le rechercher si il y a un intérêt)
Étonnamment, cela ne semble pas déranger beaucoup de programmeurs là-bas. J'ai essayé de susciter l'intérêt d'un couple de fois à la r-devel, ne sont pas significatives, en vain.
Les désavantages de l'utilisation de l' ::
de l'opérateur
- À l'aide de l'
::
opérateur pourrait frapper beaucoup d'efficacité dans certains contextes, comme Dominick Samperi souligné. - Lors de l' élaboration de votre propre forfait, vous ne pouvez même pas utiliser l'
::
de l'opérateur tout au long de votre propre code que votre code n'est pas véritable package pour le moment et donc il n'y a également aucun espace de noms encore. Si je dois d'abord en tenir à l'foo
, construire, tester, puis revenir en arrière pour tout changer pournamespace::foo
. Pas vraiment.
Les solutions possibles pour éviter ces problèmes
-
Réaffecter chaque fonction de chaque paquet à une variable qui suit certaines conventions de nommage, par exemple,
namespace..foo
afin d'éviter les inefficacités liées auxnamespace::foo
(je l'ai décrit une fois ici). Avantages: il fonctionne. Inconvénients: il est maladroit et on double la quantité de mémoire utilisée. - Simuler un espace de noms lors du développement de votre colis. AFAIU, ce n'est pas vraiment possible, au moins j'ai dit donc, pour revenir ensuite.
- Rendre obligatoire pour utiliser
namespace::foo
. À mon humble avis, ce serait la meilleure chose à faire. Bien sûr, nous perdrions une certaine mesure, de la simplicité, mais là encore, la R de l'univers n'est tout simplement pas simple plus (au moins, il n'est pas aussi simple que dans le début des 00's).
Et que dire de (formelle) des classes?
Outre les aspects décrits ci-dessus, ::
fonctionne assez bien pour les fonctions/méthodes. Mais ce que sur les définitions de classe?
Prendre le paquet heuredate avec c'est classe timeDate
. Dire un paquet vient le long qui a également une classe timeDate
. Je ne vois pas comment je pourrais explicitement état que je voudrais une nouvelle instance de la classe timeDate
depuis l'un des deux paquets.
Quelque chose comme cela ne fonctionnera pas:
new(timeDate::timeDate)
new("timeDate::timeDate")
new("timeDate", ns="timeDate")
Qui peut être un énorme problème, car de plus en plus de personnes passent à la programmation orientée objet-style pour leur R les paquets, conduisant à beaucoup de définitions de classe. Si il est une façon d'aborder explicitement l'espace de noms de la définition d'une classe, je serais très heureux d'un pointeur!
Conclusion
Même si c'était un peu long, j'espère que j'ai été en mesure de préciser le cœur du problème/question, et que je peux faire plus de sensibilisation ici.
Je pense que devtools et mvbutils avez quelques approches qui peuvent être en vaut la propagation, mais je suis sûr qu'il ya plus à dire.