length - seo title description checker




Melhor explicação de quando usar Importações/Dependências (3)

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

A única vez que você deve usar 'Depende' é quando o seu pacote é um complemento ou um complemento para outro pacote, onde o usuário final estará usando funções do seu pacote e do pacote 'Dependos' em seu código. Se o seu usuário final estiver apenas interagindo com suas funções, e o outro pacote estará apenas trabalhando nos bastidores, use 'Importações'.

A ressalva para isso é que se você adicionar um pacote a 'Importações', como você normalmente deveria, seu código precisará referir-se a funções daquele pacote, usando a sintaxe do namespace completo, por exemplo dplyr::mutate() , ao invés de apenas mutate() . Isso torna o código um pouco mais complicado de ler, mas é um pequeno preço a pagar por uma melhor higiene do pacote.

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

As regras gerais são

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

Alguém pode fornecer um pouco mais de clareza sobre isso? Como sei quando meu pacote precisa apenas de namespaces carregados versus quando eu preciso de um pacote a ser 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 um pouco de 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 (pesquise por 'Imports v Depends'). O visual torna muito mais fácil de entender.


Chambers no SfDA diz para usar 'Imports' quando este pacote usa um mecanismo 'namespace' e já que todos os pacotes são agora obrigados a tê-los, então a resposta agora pode ser sempre usar 'Importações'. No passado, os pacotes poderiam ter sido carregados sem ter namespaces e, nesse caso, você precisaria usar Depends.


"Imports" é mais seguro que "Depends" (e também faz com que um pacote o use como "melhor cidadão" em relação a outros pacotes que usam "Depends" ).

Uma diretiva "Depends" 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 identicamente identificada anteriormente no caminho de pesquisa. Chambers ( no SoDA ) usa o exemplo da função "gam" , que é encontrada nos pacotes gam e mgcv . Se dois outros pacotes foram carregados, um deles dependendo do gam e um dependendo do mgcv , a função encontrada pelas chamadas ao gam() dependeria da ordem em que esses dois pacotes foram anexados. Não é bom.

Uma diretiva "Imports" coloca o pacote importado em <imports:packageName> (pesquisado imediatamente após <namespace:packageName> ), em vez de no caminho de pesquisa regular. Se qualquer um dos pacotes no exemplo acima usasse o mecanismo "Imports" , os problemas seriam melhorados de duas maneiras. (1) O pacote poderia ganhar controle sobre qual função mgcv é usada. (2) Mantendo o caminho de busca principal livre dos objetos importados, ele não iria potencialmente quebrar a dependência do outro pacote na outra função mgcv .

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

Editado para adicionar uma advertência importante:

Infelizmente, há uma exceção comum aos conselhos acima: se o seu pacote depende de um pacote A que "Depends" de outro pacote B , seu pacote provavelmente precisará anexar A com uma "Depends Diretriz de "Depends .

Isso ocorre porque as funções no pacote A foram escritas com a expectativa de que o pacote B e suas funções seriam anexadas ao caminho search() .

Uma diretiva "Depends" carregará e anexará o pacote A , no qual a diretiva "Depends" próprio pacote A , em uma reação em cadeia, fará com que o pacote B seja carregado e anexado também. As funções no pacote A poderão, então, encontrar as funções no pacote B em que elas dependem.

Uma diretiva "Imports" será carregada, mas não anexará o pacote A e não carregará nem anexará o pacote B ( "Imports" , afinal, espera que os autores de pacotes usem o mecanismo de namespace, e que o pacote A esteja usando "Imports" para apontar para quaisquer funções em B que precisem acessar.) Chama por suas funções para quaisquer funções em O pacote A que depende de funções no pacote B irá falhar.

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

  1. Ter seu pacote anexar o pacote A usando uma diretiva "Depends" .
  2. Melhor a longo prazo, entre em contato com o mantenedor do pacote A e peça-lhes para fazer um trabalho mais cuidadoso na construção de seu espaço de nome (nas palavras de Martin Morgan nesta resposta relacionada ).