clojure namespaces

Diferencia en Clojure entre uso y requerimiento



namespaces (1)

La respuesta está en los documentos:

user> (doc use) ------------------------- clojure.core/use ([& args]) Like ''require, but also refers to each lib''s namespace using clojure.core/refer. Use :use in the ns macro in preference to calling this directly. ''use accepts additional options in libspecs: :exclude, :only, :rename. The arguments and semantics for :exclude, :only, and :rename are the same as those documented for clojure.core/refer. nil

Y el largo para require:

user> (doc require) ------------------------- clojure.core/require ([& args]) Loads libs, skipping any that are already loaded. Each argument is either a libspec that identifies a lib, a prefix list that identifies multiple libs whose names share a common prefix, or a flag that modifies how all the identified libs are loaded. Use :require in the ns macro in preference to calling this directly. Libs A ''lib'' is a named set of resources in classpath whose contents define a library of Clojure code. Lib names are symbols and each lib is associated with a Clojure namespace and a Java package that share its name. A lib''s name also locates its root directory within classpath using Java''s package name to classpath-relative path mapping. All resources in a lib should be contained in the directory structure under its root directory. All definitions a lib makes should be in its associated namespace. ''require loads a lib by loading its root resource. The root resource path is derived from the lib name in the following manner: Consider a lib named by the symbol ''x.y.z; it has the root directory <classpath>/x/y/, and its root resource is <classpath>/x/y/z.clj. The root resource should contain code to create the lib''s namespace (usually by using the ns macro) and load any additional lib resources. Libspecs A libspec is a lib name or a vector containing a lib name followed by options expressed as sequential keywords and arguments. Recognized options: :as :as takes a symbol as its argument and makes that symbol an alias to the lib''s namespace in the current namespace. Prefix Lists It''s common for Clojure code to depend on several libs whose names have the same prefix. When specifying libs, prefix lists can be used to reduce repetition. A prefix list contains the shared prefix followed by libspecs with the shared prefix removed from the lib names. After removing the prefix, the names that remain must not contain any periods. Flags A flag is a keyword. Recognized flags: :reload, :reload-all, :verbose :reload forces loading of all the identified libs even if they are already loaded :reload-all implies :reload and also forces loading of all libs that the identified libs directly or indirectly load via require or use :verbose triggers printing information about each load, alias, and refer Example: The following would load the libraries clojure.zip and clojure.set abbreviated as ''s''. (require ''(clojure zip [set :as s])) nil

Ambos hacen lo mismo, pero el use da un paso extra y crea asignaciones para las cosas en el espacio de nombres requerido en el espacio de nombres actual. De esa manera, en lugar de hacer algo de some.namespace/name , solo te refieres a él como name . Aunque a veces esto es conveniente, es mejor usar require o seleccionar los vars individuales que desee en lugar de extraer todo el espacio de nombre. De lo contrario, podría tener problemas con el sombreado (donde se prefiere una var sobre otra del mismo nombre).

Si no desea usar require, pero sabe qué vars desea del espacio de nombres, puede hacer esto:

(ns whatever (:use [some.namespace :only [vars you want]]))

Si no sabes qué vars vas a necesitar, o si necesitas mucho, es mejor usar require. Incluso cuando lo requiera, no siempre tiene que escribir el nombre totalmente calificado. Puedes hacerlo:

(ns whatever (:require [some.namespace :as sn]))

y luego puedes usar vars de algún espacio de nombres como este: (sn/somefunction arg1 arg2)

Y para responder a su última pregunta: intente usar solo: require y: use dentro de (ns ...). Es mucho más limpio de esta manera. No use y require fuera de (ns ..) a menos que tenga una buena razón para ello.

Recientemente comencé a aprender Clojure y estoy teniendo un poco de dificultad para abarcar los espacios de nombres. Como dijo el creador de Clojure, los recién llegados a menudo luchan por obtener el concepto correcto. No entiendo claramente la diferencia entre (use ...) y (require ...) . Por ejemplo, jugar en el REPL si digo (use ''clojure.contrib.str-utils2) recibo advertencias sobre las funciones en el espacio de nombres clojure.core reemplazadas por las de clojure.contrib.str-utils2, pero eso no sucede cuando uso (require ''clojure.contrib.str-utils2) . No estoy seguro de que siempre quiera reemplazar lo que está en clojure.core, así que ¿alguien puede señalar algunas de las mejores prácticas para importar material externo y administrar espacios de nombres en Clojure?

Ah, y también, ¿cuándo debería usar :use y :require ? Solo adentro (ns ....) ?

Gracias por adelantado.