2011-12-26 16 views
122

W „Writing R Extensions” instrukcja zawiera następujące wytyczne dotyczące kiedy używać przywozu lub Zależy:Lepsze wyjaśnienie kiedy użyć Import/Zależy

The general rules are

  • Packages whose namespace only is needed to load the package using library(pkgname) must be listed in the ‘Imports’ field and not in the ‘Depends’ field.
  • Packages that need to be attached to successfully load the package using library(pkgname) must be listed in the ‘Depends’ field, only.

Czy ktoś może dostarczyć nieco większą jasność w tej sprawie? Skąd mam wiedzieć, kiedy mój pakiet potrzebuje tylko przestrzeni nazw załadowanych w porównaniu do potrzebnego pakietu do dołączenia? Jakie są przykłady obu? Myślę, że typowy pakiet to tylko zbiór funkcji, które czasami wywołują funkcje w innych pakietach (gdzie część pracy została już zakodowana). Czy powyższy scenariusz 1 lub 2 jest powyżej?

Edit

Napisałem blog post z odcinka na tym konkretnym temacie (wyszukaj 'przywóz v Zależy'). Wizualizacje znacznie ułatwiają zrozumienie.

+0

Twoim blogu powiedział mi wszystko o strukturze pakietu, z powrotem, gdy zacząłem planuje [* moduły *] (https://github.com/klmr/modules). Dzięki! –

Odpowiedz

117

"Imports" jest bezpieczniejsza niż "Depends" (a także sprawia, że ​​pakiet używa go "lepszego obywatela" w odniesieniu do innych pakietów, które używają "Depends").

Dyrektywa "Depends" próbuje zapewnić, że funkcja z innego pakietu jest dostępna przez dołączenie innego pakietu do głównej ścieżki wyszukiwania (tj. Listy środowisk zwróconych przez search()). Tej strategii można jednak zapobiec, jeśli inny pakiet, załadowany później, umieszcza identycznie nazwaną funkcję wcześniej na ścieżce wyszukiwania. Komora() wykorzystuje przykład funkcji "gam", która znajduje się zarówno w paczkach gam, jak i. Jeśli załadowano dwa inne pakiety, jeden z nich w zależności od gam i jeden zależny od mgcv, funkcja znaleziona przez wywołania gam() zależy od kolejności, w jakiej te dwa pakiety zostały dołączone. Niedobrze.

dyrektywę "Imports" umieszcza importowaną pakiet w <imports:packageName> (wyszukane natychmiast po <namespace:packageName>), zamiast na zwykłej ścieżce wyszukiwania. Jeśli którykolwiek z pakietów w powyższym przykładzie użyłby mechanizmu "Imports", sprawy zostałyby poprawione na dwa sposoby. (1) Pakiet sam uzyskałby kontrolę nad funkcją mgcv. (2) Utrzymując główną ścieżkę wyszukiwania z importowanych obiektów, nie mógłby potencjalnie złamać zależności drugiego pakietu od innej funkcji mgcv.

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


Edited by dodać ważną zastrzeżenie:

Jest jeden niestety powszechne wyjątkiem rad powyżej: jeśli pakiet opiera się na opakowaniu A która sama "Depends" na innym opakowaniu B, twój pakiet prawdopodobnie będzie wymagał dołączenia A z dyrektywą "Depends.

To dlatego funkcje w pakiecie A zostały napisane z oczekiwaniem, że pakiet B i jego funkcje zostaną dołączone do ścieżkisearch().

Dyrektywa "Depends" ładuje i dołączać pakiet A, w tym momencie pakiet A „własnym dyrektywy "Depends" się w reakcji łańcuchowej pakiet przyczyną B być ładowane i dołączony również. Funkcje w pakiecie A będą wtedy mogły znaleźć funkcje w pakiecie B, na których polegają.

dyrektywę "Imports" załaduje ale nie dołączyć pakiet A i ani obciążenie ani dołączyć pakiet B. ("Imports", mimo wszystko, oczekuje, że twórcy pakietów używają mechanizmu przestrzeni nazw, i że pakiet A będzie używał "Imports" do wskazywania dowolnej funkcji w B, że potrzebuje dostępu.) Połączenia przez twoje funkcje z dowolnymi funkcjami w pakiecie A, które polegają na na funkcjach w pakiecie B w konsekwencji nie powiedzie się.

tylko dwa rozwiązania są albo:

  1. Mają swój pakiet dołączyć pakiet A stosując dyrektywę "Depends".
  2. Lepiej w dłuższej perspektywie, skontaktuj się z opiekunem pakietu A i poproś go o wykonanie bardziej uważnej pracy nad stworzeniem ich przestrzeni nazw (według słów Martina Morgana w this related answer).
+0

ah! dzięki Josh, jesteś dzisiaj na fali. – SFun28

+0

Cóż, obaj byli interesującymi pytaniami, a ponieważ niedawno zaczęłam pakować niektóre z moich własnych projektów, podróżowałem tymi samymi ścieżkami myślowymi jak ty;) –

+1

Po zadaniu ostatnio podobnego pytania i ostatnio silnie zmagali się z tymi kwestiami, są to subtelne i często źle komunikowane koncepcje. Skieruję cię tutaj po inne wyjaśnienie: http: // stackoverflow.com/questions/7880355/nextcoming-namespace-depends-imports-changes-for-2-14-0-niektóre-definicje-use-pl –

13

Komory w SfDA mówią, że używają "Importu", gdy ten pakiet używa mechanizmu "przestrzeni nazw", a ponieważ wszystkie pakiety są teraz wymagane, aby je mieć, wówczas odpowiedź może teraz zawsze używać "Importu". W przeszłości pakiety mogły być ładowane bez rzeczywistych przestrzeni nazw iw takim przypadku musiałbyś używać Depends.

+2

kiedy pakiet jest określony w "import" i chcę użyć funkcji w pakiecie, czy moje własne funkcje muszą wywoływać bibliotekę (...) lub czy wszystkie funkcje są już dostępne w ścieżce wyszukiwania? Co to jest SfDA? spinki do mankietów? – SFun28

+2

* Oprogramowanie do analizy danych *: http://www.springer.com/statistics/computanional+statistics/book/978-0-387-75935-7 ... jak na twoje pytania, nie znam odpowiedzi z drugiej strony, ale możesz łatwo zestroić minimalny pakiet testowy i znaleźć empirycznie odpowiedź ... –

+1

SfDA == "Oprogramowanie do analizy danych". [65] na http://www.r-project.org/doc/bib/R-books.html. Jeśli pakiet określa inny pakiet, powinien pojawić się komunikat informujący o ładowaniu zależności (encies) i importu (acjach), gdy używasz biblioteki() lub require() na konsoli. Tak, powinny być dostępne. –

23

Hadley Wickham daje łatwego wyjaśnienia (http://r-pkgs.had.co.nz/namespace.html):

Listing a package in either Depends or Imports ensures that it’s installed when needed. The main difference is that where Imports just loads the package, Depends attaches it. There are no other differences. [...]

Unless there is a good reason otherwise, you should always list packages in Imports not Depends . That’s because a good package is self-contained, and minimises changes to the global environment (including the search path). The only exception is if your package is designed to be used in conjunction with another package. For example, the analogue package builds on top of vegan. It’s not useful without vegan, so it has vegan in Depends instead of Imports . Similarly, ggplot2 should really Depend on scales, rather than Importing it.

Powiązane problemy