Melhor explicação de quando usar Imports / Depends


148

O manual " Writing R Extensions " fornece as seguintes orientações sobre quando usar Imports ou Depends:

As regras gerais são

  • Pacotes cujo espaço para nome é necessário apenas para carregar o pacote usando a biblioteca (pkgname) devem ser listados no campo 'Importações' e não no campo 'Depends'.
  • Os pacotes que precisam ser anexados para carregar o pacote com sucesso usando a biblioteca (pkgname) devem ser listados apenas no campo 'Depends'.

Alguém pode fornecer um pouco mais de clareza sobre isso? Como sei quando meu pacote precisa apenas de namespaces carregados e quando preciso que um pacote seja anexado? Quais são os exemplos de ambos? Eu acho que o pacote típico é apenas uma coleção de funções que às vezes chamam funções em outros pacotes (onde algum trabalho já foi codificado). Este cenário é 1 ou 2 acima?

Editar

Eu escrevi uma postagem no blog com uma seção sobre esse tópico específico (procure por 'Importações v Depends'). O visual facilita muito a compreensão.


1
Sua postagem no blog me contou tudo sobre a estrutura dos pacotes, quando comecei a planejar os módulos . Obrigado!
Konrad Rudolph

Respostas:


143

"Imports"é mais seguro do que "Depends"(e também torna um pacote usá-lo um 'cidadão melhor' em relação a outros pacotes que o utilizam "Depends").

Uma "Depends"diretiva tenta garantir que uma função de outro pacote esteja disponível anexando o outro pacote ao caminho de pesquisa principal (ou seja, a lista de ambientes retornados por search()). Essa estratégia pode, no entanto, ser frustrada se outro pacote, carregado posteriormente, colocar uma função com nome idêntico anteriormente no caminho da pesquisa. Chambers ( no SoDA ) usa o exemplo da função "gam", encontrada nos pacotes game mgcv. Se dois outros pacotes fossem carregados, um deles dependendo game um dependendo mgcv, a função encontrada pelas chamadas gam()dependeria da ordem em que esses dois pacotes foram anexados. Não é bom.

Uma "Imports"diretiva deve ser usada para qualquer pacote de suporte cujas funções sejam colocadas <imports:packageName>(pesquisadas imediatamente após <namespace:packageName>), em vez de no caminho de pesquisa regular. Se um dos pacotes no exemplo acima usasse o "Imports"mecanismo (que também requer importou importFromdiretivas no NAMESPACEarquivo), as questões seriam melhoradas de duas maneiras. (1) O pacote ganharia controle sobre qual mgcvfunção é usada. (2) Ao manter o caminho de pesquisa principal livre dos objetos importados, ele nem sequer quebraria a dependência do outro pacote em relação à outra mgcvfunção.

É por isso que usar namespaces é uma prática tão boa, agora é aplicada pelo CRAN e (em particular) por que usar "Imports"é mais seguro do que usar "Depends".


Editado para adicionar uma ressalva importante:

uma exceção, infelizmente, comuns ao conselho acima: se o seu pacote depende de um pacote Aque se "Depends"em outro pacote B, o pacote provavelmente precisará anexar Acom uma "Dependsdirectiva.

Isso ocorre porque as funções no pacote Aforam escritas com a expectativa de que o pacote Be suas funções sejam anexadas ao search()caminho .

Uma "Depends"diretiva carregará e anexará o pacote A; nesse momento, Aa "Depends"diretiva do próprio pacote , em uma reação em cadeia, fará com que o pacote Bseja carregado e anexado também. As funções no pacote Apoderão encontrar as funções no pacote Bnas quais elas dependem.

Uma "Imports"diretiva carregará, mas não anexará o pacote A, nem carregará nem anexará o pacote B. ( "Imports"afinal de contas, espera que os gravadores de pacotes estejam usando o mecanismo de namespace e esse pacote Aesteja usando "Imports"para apontar para quaisquer funções nas Bquais precise acessar.) Chamadas pelas suas funções para quaisquer funções no pacote Aque dependam de funções no pacote B. consequentemente falhar.

As duas únicas soluções são:

  1. Faça seu pacote anexar pacote Ausando uma "Depends"diretiva.
  2. Melhor a longo prazo, entre em contato com o mantenedor do pacote Ae peça que ele faça um trabalho mais cuidadoso na construção de seu espaço para nome (nas palavras de Martin Morgan nesta resposta relacionada ).

1
Tendo feito recentemente uma pergunta semelhante e recentemente lutado poderosamente com essas questões, esses são conceitos sutis e frequentemente pouco comunicados. Vou indicar você aqui para outra explicação: stackoverflow.com/questions/7880355/…
Bryan Hanson

@BryanHanson - Obrigado por escrever as notas nesse link. As diferenças entre os requisitos de versão Importse Dependswrt e a verificação de exemplos nos .Rdarquivos são realmente sutis e vale a pena conhecer.
Josh O'Brien

1
A ressalva sobre dependências que usam 'Depends' é uma coisa horrível. Significa que basicamente não posso usar 'Importações' no meu pacote até que todos os outros também estejam. = (
Ken Williams

Uma coisa em que ainda não estou claro é: se estou escrevendo um pacote e quero Imports: ggplot2, por que meu pacote não encontra a autoplotfunção? Obviamente, Dependsanexa a biblioteca de pacotes ggplot2e, portanto, não há problema. por exemplo, tenho uma função autoplot.myFunction() que usa a @import ggplot2tag e meu pacote possui, Imports: ggplot2mas recebo um erro: Error in eval(expr, envir, enclos) : could not find function "autoplot"quando tento usá-la.
Nathaneastwood 16/03/2015

1
@ Willem Obrigado. Você está certo, é claro, e eu editei a resposta para esclarecer o conteúdo enganoso. Parte do que dificultou a resposta é que, embora o OP tenha enquadrado sua pergunta com referência às seções Dependse , ele estava realmente perguntando sobre o que "importar" uma função (em vez de "depender" dela) significa. Como essa última é a pergunta que tentei responder (e - suspeito - o que a maioria das pessoas que busca essa resposta está querendo saber), deixarei a resposta inalterada. ImportsDESCRIPTION
Josh O'Brien

31

Hadley Wickham dá uma explicação fácil ( http://r-pkgs.had.co.nz/namespace.html ):

Listar um pacote em Dependsou Importsgarante que ele seja instalado quando necessário. A principal diferença é que, onde Importsapenas carrega o pacote, o Dependsanexa. Não há outras diferenças. [...]

A menos que exista uma boa razão, você deve sempre listar os pacotes Importsnão Depends. Isso ocorre porque um bom pacote é independente e minimiza as alterações no ambiente global (incluindo o caminho de pesquisa). A única exceção é se o seu pacote foi projetado para ser usado em conjunto com outro pacote. Por exemplo, o pacote analógico se baseia em produtos veganos. Não é útil sem veganos, por isso é vegano em Dependsvez de Imports. Da mesma forma, o ggplot2 deve realmente depender de escalas, em vez de importá-lo.


15

Chambers no SfDA diz usar 'Imports' quando este pacote usa um mecanismo de 'namespace' e como todos os pacotes agora precisam deles, a resposta agora pode ser sempre usar 'Imports'. No passado, os pacotes podiam ter sido carregados sem ter espaços para nome e, nesse caso, você precisaria usar o Depends.


2
quando um pacote é especificado em "importações" e eu quero usar uma função no pacote, minhas próprias funções precisam chamar a biblioteca (...) ou todas as funções já estão disponíveis no caminho de pesquisa? Além disso, o que é SfDA? links?
SFun28

2
Software para análise de dados : springer.com/statistics/computanional+statistics/book/… ... quanto às suas perguntas, não sei a resposta de imediato, mas você pode criar um pacote de teste mínimo com bastante facilidade e encontrar a resposta empiricamente ...
Ben Bolker

1
SfDA == "Software para análise de dados". [65] em r-project.org/doc/bib/R-books.html . Se um pacote especificar outro pacote, você deverá receber uma mensagem informando sobre o carregamento da dependência (encies) e importação (ations) ao usar a biblioteca () ou exigir () no console. Sim, eles devem estar disponíveis.
IRTFM

4
+1 - Essa é minha forte impressão também. Além disso, um pacote especificado em importações será pesquisado imediatamente após o <namespace:packageName>, como parte de <imports:packageName>. Nenhuma chamada adicional library()é necessária, e R não o notificará no console no momento do carregamento do pacote, a menos que o Importpacote ed não possa ser encontrado.
Josh O'Brien

5

Aqui está uma pergunta simples para ajudá-lo a decidir qual usar:

Seu pacote exige que o usuário final tenha acesso direto às funções de outro pacote?

  • NÃO -> Importações (resposta mais comum)
  • SIM -> Depende

O único momento em que você deve usar 'Depends' é quando o seu pacote é um complemento ou acessório para outro pacote, em que o usuário final utilizará funções do seu pacote e do pacote 'Depends' no código. Se o seu usuário final estiver interagindo apenas com as suas funções e o outro pacote apenas estiver trabalhando nos bastidores, use 'Importações'.

A ressalva disso é que, se você adicionar um pacote a 'Importações', como normalmente deveria, seu código precisará se referir às funções desse pacote, usando a sintaxe completa do espaço para nome, por exemplo dplyr::mutate(), em vez de apenas mutate(). Isso torna o código um pouco mais complicado de ler, mas é um preço pequeno a pagar por uma melhor higiene das embalagens.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.