Lepsze wyjaśnienie, kiedy korzystać z importu / zależy

Podręcznik "zapisywanie rozszerzeń R " zawiera następujące wskazówki, kiedy używać importu lub zależy:

Ogólne zasady to

  • Pakiety, których przestrzeń nazw jest potrzebna tylko do załadowania pakietu za pomocą biblioteki (pkgname) , muszą być wymienione w polu 'Imports', a nie w Pole 'zależy'.
  • pakiety, które muszą być dołączone, aby pomyślnie załadować pakiet za pomocą biblioteki (pkgname), muszą być wymienione tylko w polu 'Depends'.

Czy ktos moze podac troche wiecej jasnosci w tej sprawie? Skąd mam wiedzieć, że mój pakiet wymaga załadowanych tylko przestrzeni nazw, a nie kiedy pakiet ma być dołączony? Jakie są przykłady obu? Myślę, że typowy Pakiet jest tylko zbiorem funkcji, które czasami wywołują funkcje w innych pakietach(gdzie trochę pracy zostało już zakodowane). Czy to scenariusz 1 Czy 2 powyżej?

Edit

Napisałem wpis na blogu z sekcją na ten konkretny temat (Szukaj 'Import v zależy'). Wizualizacje sprawiają, że jest to o wiele łatwiejsze do zrozumienia.

 128
r
Author: Hedgehog, 2011-12-26

4 answers

"Imports" jest bezpieczniejszy niż "Depends" (a także sprawia, że pakiet z niego korzystający staje się "lepszym obywatelem" w stosunku do innych pakietów, które używają "Depends").

Dyrektywa "Depends" próbuje zapewnić dostępność funkcji z innego pakietu poprzez dołączenie drugiego pakietu do głównej ścieżki wyszukiwania(tj. listy środowisk zwracanych przez search()). Ta strategia może jednak zostać udaremniona, jeśli inny pakiet, załadowany później, umieści wcześniej identycznie nazwaną funkcję na ścieżce wyszukiwania. Chambers ( w SoDA ) wykorzystuje przykład funkcji "gam", która znajduje się zarówno w pakietach gam, jak i mgcv. Jeśli załadowano dwa inne pakiety, jeden zależny od gam i jeden zależny od mgcv, funkcja znaleziona przez wywołania do gam() zależałaby od kolejności, w jakiej te dwa pakiety zostały dołączone. Niedobrze.

Dyrektywa "Imports" umieszcza importowany pakiet w <imports:packageName> (wyszukiwany bezpośrednio po <namespace:packageName>), zamiast w zwykłej ścieżce wyszukiwania. Jeśli któryś z pakiety w powyższym przykładzie używały mechanizmu "Imports", sprawy byłyby ulepszone na dwa sposoby. (1) pakiet sam przejmie kontrolę nad tym, która funkcja mgcv jest używana. (2) utrzymując główną ścieżkę wyszukiwania z dala od importowanych obiektów, nie mogłoby to nawet potencjalnie zerwać zależności innego pakietu od innej funkcji mgcv.

Dlatego używanie przestrzeni nazw jest tak dobrą praktyką, dlaczego jest teraz egzekwowane przez CRAN, a w szczególności dlaczego używanie "Imports" jest bezpieczniejsze niż używanie "Depends".


Edytowano, aby dodać ważne zastrzeżenie:

Istnieje jeden niestety powszechny wyjątek od powyższej porady: Jeśli Twój Pakiet opiera się na pakiecie A, który sam "Depends" znajduje się na innym pakiecie B, prawdopodobnie Twój Pakiet będzie musiał dołączyć A z "Depends dyrektywą.

Dzieje się tak dlatego, że funkcje w pakiecie A zostały napisane z oczekiwaniem, że pakiet {[21] } i jego funkcje będą dołączone do search() ścieżka .

Dyrektywa "Depends" ładuje i dołącza pakiet A, w którym to momencie własna dyrektywa "Depends" pakietu A spowoduje, w reakcji łańcuchowej, załadowanie i dołączenie pakietu B. Funkcje w pakiecie A będą wtedy w stanie znaleźć funkcje w pakiecie B, na których się opierają.

Dyrektywa "Imports"załaduje, ale nie dołącza pakietuA i ani załadujeani dołącza pakietB. ("Imports", przecież, oczekuje, że autorzy pakietów używają mechanizmu przestrzeni nazw i że pakiet {[19] } będzie używał "Imports", aby wskazać dowolne funkcje w B, do których potrzebuje dostępu.) Wywołanie funkcji przez użytkownika do wszystkich funkcji w pakiecie A, które polegają na funkcjach w pakiecie B, w konsekwencji zakończy się niepowodzeniem.

Jedyne dwa rozwiązania to:

  1. Niech Twój Pakiet załączy pakiet A używając dyrektywy "Depends".
  2. lepiej na dłuższą metę, skontaktuj się z opiekunem pakiet A i poproś ich, aby wykonali bardziej ostrożną pracę przy konstruowaniu ich przestrzeni nazw (słowa Martina Morgana w tej powiązanej odpowiedzi).
 124
Author: Josh O'Brien,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:47:13

Hadley Wickham daje proste wyjaśnienie ( http://r-pkgs.had.co.nz/namespace.html):

Umieszczenie pakietu w Depends LUB Imports zapewnia, że jest zainstalowany w razie potrzeby. główna różnica polega na tym, że gdzie Imports po prostu ładuje paczkę, Depends dołącza ją. Nie ma innych różnice. [...]

O ile nie ma innego dobrego powodu, zawsze należy wymienić pakiety w Imports Nie Depends. to dlatego, że dobry pakiet na samodzielne i minimalizuje zmiany w środowisku globalnym (łącznie ze ścieżką wyszukiwania). jedynym wyjątkiem jest, jeśli pakiet jest przeznaczony do stosowania w połączeniu z innym pakietem. na przykład, pakiet analogowy opiera się na wegańskiej. To nie jest przydatne bez wegańskie, więc ma wegańskie w Depends zamiast Imports. Podobnie, ggplot2 powinien naprawdę zależeć od skali, a nie od importu.

 28
Author: majom,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-08-12 10:23:44

Chambers w SfDA mówi, aby używać 'Imports', gdy ten pakiet używa mechanizmu 'namespace', a ponieważ wszystkie pakiety są teraz wymagane, wtedy odpowiedzią może być zawsze użycie 'Imports'. W przeszłości Pakiety mogły być ładowane bez przestrzeni nazw i w takim przypadku trzeba było użyć Depends.

 13
Author: 42-,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-12-26 18:53:33

Oto proste pytanie, które pomoże Ci zdecydować, którego użyć:

Czy Twój Pakiet wymaga od użytkownika końcowego bezpośredniego dostępu do funkcji innego pakietu?

  • NO - > Import (najczęstsza odpowiedź)
  • Tak - > zależy

Jedynym czasem, kiedy powinieneś użyć 'Depends' jest to, gdy Twój Pakiet jest dodatkiem lub towarzyszem innego pakietu, gdzie użytkownik końcowy będzie używał funkcji zarówno z twojego pakietu, jak i pakietu 'Depends' w ich kod. Jeśli twój użytkownik końcowy będzie współpracował tylko z Twoimi funkcjami, a drugi pakiet będzie działał tylko za kulisami, użyj zamiast tego opcji "Import".

Zastrzeżenie jest takie, że jeśli dodasz pakiet do 'Imports' , 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 tylko mutate(). To sprawia, że kod jest trochę bardziej clunkier czytać, ale to niewielka cena do zapłacenia za lepszy pakiet higiena.

 2
Author: Aaron Cooley,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-03-22 17:57:12