requirecarrega libs (que ainda não foram carregadas), usefaz o mesmo e se refere aos seus namespaces com clojure.core/refer(para que você também tenha a possibilidade de usar :excludeetc como em clojure.core/refer). Ambos são recomendados para uso em nsvez de diretamente.
Se eu precisar de lib foo, para usar bar in foo, eu precisaria escrever foo / bar toda vez, certo? Por que você deseja carregar uma lib em ns, mas não a encaminha para os ns? Acho que você pode estar preocupado com colisões e não quer se incomodar em reconciliá-las, certo?
Jegschemesch
12
não ter que reconciliar colisões é um bom argumento e, geralmente, existe um estilo de programação que diz que "namespaces são uma ótima idéia, devemos ter mais" (de "The Zen of Python") - por exemplo, esse estilo recomenda não usando "using namespace foo;" em C ++, para que os leitores e mantenedores do código não precisem se preocupar "de onde vem essa barra", mas ver um foo :: bar mais explícito. require (vs use) suporta esse estilo "namespaces explícitos".
Alex Martelli
2
Alex dá uma resposta boa, mas desatualizada. Como o @overthink aponta abaixo, depois que essa resposta foi dada, o clojure idiomático recomenda o uso excessivo. Veja: dev.clojure.org/jira/browse/CLJ-879
Phil Cooper
Embora esta seja a resposta aceita e mais votada, ela é antiga e representa uma visão desatualizada. A melhor resposta é que a partir @rzv: stackoverflow.com/a/16429572/172272
Didier A.
65
É idiomático incluir funções externas com requiree refer. Você evita conflitos de espaço para nome, inclui apenas funções que realmente usa / precisa e declara explicitamente o local de cada função:
Caso contrário, você está incluindo tudo, tornando-a uma operação desnecessariamente grande e muito confusa para outros programadores descobrirem onde estão as funções.
Além disso, eu recomendo este blog como um recurso para aprender mais sobre os namespaces do Clojure.
Você sabe se existe alguma diferença no final entre (:use foo :only [bar])e (:require foo :refer [bar])? Parece estranho ter duas maneiras de fazer isso.
overthink
10
Parece que stackoverflow.com/a/10370672/69689 responde à minha pergunta. Resumindo: (:require .. :refer ..)é uma nova maneira de fazer a mesma coisa que permite que você efetue a depreciação :use, o que tem algumas desvantagens.
overthink
Bons exemplos. Eu amo exemplos, isso fez muito sentido.
Astrid
35
Certifique-se de tornar mais fácil, não exigindo que você soletre o espaço para nome toda vez que quiser chamar uma função, mas também pode causar uma confusão, criando conflitos no espaço para nome. Um bom meio termo entre "use" e "require" é apenas 'usar' as funções de um espaço para nome que você realmente usa.
por exemplo:
(use '[clojure-contrib.duck-streams: only (escritor escritor)])
ou melhor ainda, especifique-o na parte superior do arquivo na definição de namespace:
(ns com.me.project
(: use [clojure.contrib.test-is: only (deftest é executar testes)]))
Obrigado por incluir (trocadilho) a (ns ...)sintaxe; Eu estava procurando por isso, mas todos os exemplos que encontrei foram claros (use ...).
paul
1
ATUALIZAÇÃO: este método foi obsoleto agora em favor de(require '[namepase :refer [var-name1 var-name2]])
Arthur Ulfeldt
@ArthurUlfeldt Você pode querer atualizar sua resposta para incluir isso.
Bfontaine
20
Como já foi mencionado, a grande diferença é que (require 'foo), com , você se refere a nomes no espaço de nomes da biblioteca da seguinte forma: (foo/bar ...)se o fizer (use 'foo), eles estarão agora no seu espaço de nomes atual (o que quer que seja e desde que não haja conflitos) e você pode chamar eles gostam (bar ...).
Respostas:
require
carrega libs (que ainda não foram carregadas),use
faz o mesmo e se refere aos seus namespaces comclojure.core/refer
(para que você também tenha a possibilidade de usar:exclude
etc como emclojure.core/refer
). Ambos são recomendados para uso emns
vez de diretamente.fonte
É idiomático incluir funções externas com
require
erefer
. Você evita conflitos de espaço para nome, inclui apenas funções que realmente usa / precisa e declara explicitamente o local de cada função:Não preciso chamar essa função prefixando-a com seu espaço para nome:
Se você não usar,
refer
precisará prefixar o espaço para nome:Se você escolher
use
, (praticamente) sempre useonly
:Caso contrário, você está incluindo tudo, tornando-a uma operação desnecessariamente grande e muito confusa para outros programadores descobrirem onde estão as funções.
Além disso, eu recomendo este blog como um recurso para aprender mais sobre os namespaces do Clojure.
fonte
(:use foo :only [bar])
e(:require foo :refer [bar])
? Parece estranho ter duas maneiras de fazer isso.(:require .. :refer ..)
é uma nova maneira de fazer a mesma coisa que permite que você efetue a depreciação:use
, o que tem algumas desvantagens.Certifique-se de tornar mais fácil, não exigindo que você soletre o espaço para nome toda vez que quiser chamar uma função, mas também pode causar uma confusão, criando conflitos no espaço para nome. Um bom meio termo entre "use" e "require" é apenas 'usar' as funções de um espaço para nome que você realmente usa.
por exemplo:
ou melhor ainda, especifique-o na parte superior do arquivo na definição de namespace:fonte
(ns ...)
sintaxe; Eu estava procurando por isso, mas todos os exemplos que encontrei foram claros(use ...)
.(require '[namepase :refer [var-name1 var-name2]])
Como já foi mencionado, a grande diferença é que
(require 'foo)
, com , você se refere a nomes no espaço de nomes da biblioteca da seguinte forma:(foo/bar ...)
se o fizer(use 'foo)
, eles estarão agora no seu espaço de nomes atual (o que quer que seja e desde que não haja conflitos) e você pode chamar eles gostam(bar ...)
.fonte