requirecarga las bibliotecas (que aún no están cargadas), usehace lo mismo y se refiere a sus espacios de nombres con clojure.core/refer(por lo que también tiene la posibilidad de usar, :excludeetc., como con clojure.core/refer). Ambos se recomiendan para su uso en nslugar de directamente.
Si necesito lib foo, entonces para usar bar in foo, tendría que escribir foo / bar cada vez, ¿verdad? ¿Por qué querrías cargar una lib en ns pero luego no referirla a ns? Supongo que puede estar preocupado por las colisiones, y no quiere molestarse en reconciliarlas, ¿verdad?
Jegschemesch
12
no tener que conciliar las colisiones es un buen punto, y en general hay un estilo de programación que dice que "los espacios de nombres son una gran idea para tocar la bocina, deberíamos tener más" (de "The Zen of Python"), por lo que ese estilo recomienda no usar "usar el espacio de nombres foo"; en C ++, para que los lectores y mantenedores del código no tengan que preocuparse "de dónde viene esta barra", sino que verán un foo :: bar más explícito. require (vs use) admite este estilo de "espacios de nombres explícitos".
Alex Martelli
2
Alex da una buena pero anticuada respuesta. Como @overthink señala a continuación, después de dar esta respuesta, clojure idiomático recomienda requerir un uso excesivo. ver: dev.clojure.org/jira/browse/CLJ-879
Phil Cooper
Si bien esta es la respuesta aceptada y más votada, es antigua y representa una vista desactualizada. La mejor respuesta es la de @rzv: stackoverflow.com/a/16429572/172272
Didier A.
65
Es idiomático incluir funciones externas con requirey refer. Evita conflictos de espacio de nombres, solo incluye funciones que realmente usa / necesita, y declara explícitamente la ubicación de cada función:
De lo contrario, está incluyendo todo, lo que lo convierte en una operación innecesariamente grande y muy confusa para que otros programadores encuentren dónde viven las funciones.
Además, recomiendo este blog como un recurso para aprender más sobre los espacios de nombres de Clojure.
¿Sabes si hay alguna diferencia al final entre (:use foo :only [bar])y (:require foo :refer [bar])? Parece extraño tener dos formas de hacer esto.
pensar demasiado el
10
Parece que stackoverflow.com/a/10370672/69689 responde mi pregunta. En resumen: (:require .. :refer ..)es una nueva forma de hacer lo mismo que le permite desaprobar efectivamente :use, lo que tiene algunos inconvenientes.
pensar demasiado el
Bien dando ejemplos. Me encantan los ejemplos, esto tiene mucho sentido.
Astrid
35
El uso seguro hace que sea más fácil al no requerir que deletree el espacio de nombres cada vez que desee llamar a una función, aunque también puede causar problemas creando conflictos de espacio de nombres. Un buen término medio entre "usar" y "requerir" es solo "usar" las funciones de un espacio de nombres que realmente usa.
por ejemplo:
(use '[clojure-contrib.duck-streams: only (escritor lector)])
o incluso mejor, especifíquelo en la parte superior del archivo en la definición del espacio de nombres:
(ns com.me.project
(: use [clojure.contrib.test-is: only (deftest es run-tests)]))
Gracias por incluir (juego de palabras) la (ns ...)sintaxis; Había estado buscando eso, pero todos los ejemplos que encontré eran simples (use ...).
Paul
1
ACTUALIZACIÓN: este método ha quedado obsoleto ahora a favor de(require '[namepase :refer [var-name1 var-name2]])
Arthur Ulfeldt
@ArthurUlfeldt Es posible que desee actualizar su respuesta para incluir (juego de palabras) esto.
bfontaine
20
Como se ha mencionado, la gran diferencia es que con (require 'foo), luego se refiere a los nombres en el espacio de nombres de la biblioteca de la siguiente manera: (foo/bar ...)si lo hace (use 'foo), ahora están en su espacio de nombres actual (sea lo que sea y siempre que no haya conflictos) y puede llamar como ellos (bar ...).
Respuestas:
require
carga las bibliotecas (que aún no están cargadas),use
hace lo mismo y se refiere a sus espacios de nombres conclojure.core/refer
(por lo que también tiene la posibilidad de usar,:exclude
etc., como conclojure.core/refer
). Ambos se recomiendan para su uso enns
lugar de directamente.fuente
Es idiomático incluir funciones externas con
require
yrefer
. Evita conflictos de espacio de nombres, solo incluye funciones que realmente usa / necesita, y declara explícitamente la ubicación de cada función:No tengo que invocar esta función con el prefijo con su espacio de nombres:
Si no lo usa
refer
, necesitará ponerle el prefijo con el espacio de nombres:Si eliges en su
use
lugar, (más o menos) siempre usaonly
:De lo contrario, está incluyendo todo, lo que lo convierte en una operación innecesariamente grande y muy confusa para que otros programadores encuentren dónde viven las funciones.
Además, recomiendo este blog como un recurso para aprender más sobre los espacios de nombres de Clojure.
fuente
(:use foo :only [bar])
y(:require foo :refer [bar])
? Parece extraño tener dos formas de hacer esto.(:require .. :refer ..)
es una nueva forma de hacer lo mismo que le permite desaprobar efectivamente:use
, lo que tiene algunos inconvenientes.El uso seguro hace que sea más fácil al no requerir que deletree el espacio de nombres cada vez que desee llamar a una función, aunque también puede causar problemas creando conflictos de espacio de nombres. Un buen término medio entre "usar" y "requerir" es solo "usar" las funciones de un espacio de nombres que realmente usa.
por ejemplo:
o incluso mejor, especifíquelo en la parte superior del archivo en la definición del espacio de nombres:fuente
(ns ...)
sintaxis; Había estado buscando eso, pero todos los ejemplos que encontré eran simples(use ...)
.(require '[namepase :refer [var-name1 var-name2]])
Como se ha mencionado, la gran diferencia es que con
(require 'foo)
, luego se refiere a los nombres en el espacio de nombres de la biblioteca de la siguiente manera:(foo/bar ...)
si lo hace(use 'foo)
, ahora están en su espacio de nombres actual (sea lo que sea y siempre que no haya conflictos) y puede llamar como ellos(bar ...)
.fuente