Podręcznik „ Pisanie rozszerzeń języka R ” zawiera następujące wskazówki dotyczące używania opcji Import lub zależności:
Ogólne zasady to
- Pakiety, których przestrzeń nazw jest potrzebna tylko do załadowania pakietu przy użyciu biblioteki (pkgname), muszą być wymienione w polu „Import”, a nie w polu „Depends”.
- Pakiety, które muszą zostać dołączone, aby pomyślnie załadować pakiet przy użyciu biblioteki (nazwa pakietu), muszą być wymienione tylko w polu „Zależności”.
Czy ktoś może wyjaśnić to nieco lepiej? Skąd mam wiedzieć, kiedy mój pakiet wymaga załadowania tylko przestrzeni nazw, a kiedy muszę dołączyć pakiet? Jakie są przykłady obu? Myślę, że typowy pakiet to po prostu zbiór funkcji, które czasami wywołują funkcje w innych pakietach (gdzie część pracy została już zakodowana). Czy ten scenariusz 1 czy 2 jest powyżej?
Edytować
Napisałem post na blogu z sekcją poświęconą temu konkretnemu tematowi (wyszukaj frazę „Imports v Depends”). Wizualizacje znacznie ułatwiają zrozumienie.
Odpowiedzi:
"Imports"
jest bezpieczniejszy niż"Depends"
(a także sprawia, że korzystający z niego pakiet jest „lepszym obywatelem” w stosunku do innych pakietów, które go używają"Depends"
).A
"Depends"
dyrektywa próby w celu zapewnienia, że funkcja z innego pakietu jest dostępna dołączając drugą paczkę do głównej ścieżce wyszukiwania (czyli listę środowisk zwróconych przezsearch()
). Ta strategia może jednak zostać udaremniona, jeśli inny pakiet załadowany później umieści identycznie nazwaną funkcję wcześniej na ścieżce wyszukiwania. Chambers ( w SoDA ) używa przykładu funkcji"gam"
, który znajduje się zarówno w pakiecie , jakgam
imgcv
. Gdyby załadowano dwa inne pakiety, jeden z nich zależny,gam
a drugi zależny odmgcv
, funkcja znaleziona przez wywołaniagam()
zależałaby od kolejności, w jakiej te dwa pakiety zostały dołączone. Niedobrze."Imports"
Dyrektywa powinna być stosowana dla każdego pakietu wspierającego, którego funkcje mają być umieszczone w<imports:packageName>
(poszukiwanej natychmiast po<namespace:packageName>
), zamiast na zwykłej ścieżce wyszukiwania. Gdyby któryś z pakietów w powyższym przykładzie używał"Imports"
mechanizmu (który również wymagaimport
lubimportFrom
dyrektyw wNAMESPACE
pliku), sytuacja uległaby poprawie na dwa sposoby. (1) Pakiet sam zyskałby kontrolę nadmgcv
używaną funkcją. (2) Utrzymując główną ścieżkę wyszukiwania z dala od importowanych obiektów, nie spowodowałoby to nawet potencjalnego zerwania zależności innego pakietu od innejmgcv
funkcji.Dlatego używanie przestrzeni nazw jest tak dobrą praktyką, dlatego jest obecnie wymuszane przez CRAN i (w szczególności), dlaczego używanie
"Imports"
jest bezpieczniejsze niż używanie"Depends"
.Zmieniono, aby dodać ważne zastrzeżenie:
Jest jeden niestety powszechne wyjątkiem rad powyżej: jeśli pakiet opiera się na pakiet
A
, który sam"Depends"
na inny pakietB
, pakiet będzie prawdopodobnie musiał dołączyćA
z"Depends
dyrektywą.Dzieje się tak, ponieważ funkcje w pakiecie
A
zostały napisane z oczekiwaniem, że pakietB
i jego funkcje zostaną dołączone dosearch()
ścieżki ."Depends"
Dyrektywy ładuje i dołączać pakietA
, w którym to momencie pakietA
jest własny"Depends"
Dyrektywa będzie w reakcji łańcuchowej pakiet przyczynąB
być ładowane i dołączony również. Funkcje w pakiecieA
będą wtedy mogły znaleźć funkcje w pakiecie,B
na których polegają."Imports"
Dyrektywa będzie ładować, ale nie przywiązują pakietA
i będzie ani obciążenia ani dołączyć pakietB
. ("Imports"
Mimo wszystko oczekuje, że autorzy pakietów korzysta mechanizm przestrzeni nazw, a pakietA
będzie używał"Imports"
do punktu do jakichkolwiek funkcji wB
które potrzebują to dostęp.) Połączeń telefonicznych funkcji do jakichkolwiek funkcji w pakiecieA
, które opierają się na funkcjach w opakowaniuB
woli w konsekwencji zawiedzie.Jedyne dwa rozwiązania to:
A
za pomocą"Depends"
dyrektywy.A
i poproś go, aby wykonał bardziej ostrożną pracę przy konstruowaniu ich przestrzeni nazw (słowami Martina Morgana w tej powiązanej odpowiedzi ).źródło
Imports
iDepends
wrt oraz sprawdzaniem przykładów w.Rd
plikach są rzeczywiście subtelne i warte poznania.Imports: ggplot2
, dlaczego mój pakiet nie znajdujeautoplot
funkcji? OczywiścieDepends
dołącza bibliotekę pakietów,ggplot2
więc nie ma problemu. np. mam funkcję,autoplot.myFunction()
która używa@import ggplot2
tagu, a mój pakiet ma,Imports: ggplot2
ale pojawia się błąd:Error in eval(expr, envir, enclos) : could not find function "autoplot"
kiedy próbuję go użyć.Depends
i , tak naprawdę pytał o to, co oznacza „importowanie” funkcji (a nie „zależność” od niej). Ponieważ to ostatnie jest pytaniem, na które próbowałem odpowiedzieć (i - jak podejrzewam - co większość osób szukających tej odpowiedzi chce wiedzieć), w przeciwnym razie pozostawię odpowiedź bez zmian.Imports
DESCRIPTION
Hadley Wickham podaje proste wyjaśnienie ( http://r-pkgs.had.co.nz/namespace.html ):
źródło
Chambers w SfDA mówi, że należy używać opcji „Import”, gdy ten pakiet używa mechanizmu „przestrzeni nazw”, a ponieważ wszystkie pakiety muszą teraz je mieć, odpowiedzią może być teraz zawsze „Import”. W przeszłości pakiety mogły być ładowane bez rzeczywistych przestrzeni nazw iw takim przypadku musiałbyś użyć Depends.
źródło
<namespace:packageName>
, jako część<imports:packageName>
. Żadne dalsze wywołanie nielibrary()
jest potrzebne, a R nie powiadomi cię przy konsoli w czasie ładowania pakietu, chyba żeImport
nie można znaleźć pakietu ed.Oto proste pytanie, które pomoże Ci zdecydować, którego użyć:
Czy Twój pakiet wymaga, aby użytkownik końcowy miał bezpośredni dostęp do funkcji innego pakietu?
Jedynym przypadkiem, w którym powinieneś używać opcji „Depends”, jest sytuacja, gdy Twój pakiet jest dodatkiem lub dodatkiem do innego pakietu, w którym użytkownik końcowy będzie używał funkcji zarówno z Twojego pakietu, jak i pakietu „Depends” w swoim kodzie. Jeśli twój użytkownik końcowy będzie łączył się tylko z twoimi funkcjami, a drugi pakiet będzie wykonywał pracę tylko za kulisami, użyj zamiast tego opcji „Import”.
Jedynym zastrzeżeniem jest to, że jeśli dodasz pakiet do 'Importów', jak zwykle powinieneś, twój kod będzie musiał odnosić się do funkcji z tego pakietu, używając pełnej składni przestrzeni nazw, np.
dplyr::mutate()
Zamiast justmutate()
. Sprawia to, że kod jest nieco trudniejszy do odczytania, ale jest to niewielka cena za lepszą higienę opakowania.źródło