Quelqu'un peut-il expliquer la différence entre useet require, à la fois lorsqu'il est utilisé directement et au fur :useet à mesure :requiredans la nsmacro?
Voir aussi stackoverflow.com/questions/10358149/… en ce qui concerne la macro ns; dans clojure 1.4, il est suggéré d'utiliser: require de préférence à: use
Korny
Réponses:
101
requirecharge les bibliothèques (qui ne sont pas déjà chargées), usefait la même chose et fait référence à leurs espaces de noms avec clojure.core/refer(vous avez donc également la possibilité d'utiliser :excludeetc. comme avec clojure.core/refer). Les deux sont recommandés pour une utilisation dans nsplutôt que directement.
Si j'ai besoin de lib foo, alors pour utiliser bar dans foo, je devrais écrire foo / bar à chaque fois, non? Pourquoi voudriez-vous charger une bibliothèque dans ns mais ne pas la référencer dans le ns? Je suppose que vous vous inquiétez peut-être des collisions et que vous ne voulez pas vous soucier de les réconcilier, non?
Jegschemesch
12
ne pas avoir à réconcilier les collisions est un bon point, et plus généralement il y a un style de programmation qui dit "les espaces de noms sont une excellente idée, nous devrions en avoir plus" (de "Le Zen de Python") - donc par exemple ce style recommande ne pas utiliser "using namespace foo;" en C ++, pour que les lecteurs et les responsables du code n'aient pas à s'inquiéter de "d'où vient cette barre" mais voient plutôt un toto :: bar plus explicite. require (vs use) prend en charge ce style "d'espaces de noms explicites".
Alex Martelli
2
Alex donne une bonne réponse mais dépassée. Comme @overthink le souligne ci-dessous, après que cette réponse ait été donnée, clojure idiomatique recommande d'exiger une utilisation excessive. voir: dev.clojure.org/jira/browse/CLJ-879
Phil Cooper
Bien que ce soit la réponse acceptée et la plus votée, elle est ancienne et représente une vue dépassée. La meilleure réponse est celle de @rzv: stackoverflow.com/a/16429572/172272
Didier A.
65
Il est idiomatique d'inclure des fonctions externes avec requireet refer. Vous évitez les conflits d'espace de noms, vous n'incluez que les fonctions que vous utilisez réellement / dont vous avez réellement besoin et vous déclarez explicitement l'emplacement de chaque fonction:
Sinon, vous incluez tout, ce qui en fait à la fois une opération inutilement volumineuse et très déroutante pour les autres programmeurs de trouver où se trouvent les fonctions.
En outre, je recommande vivement ce blog comme ressource pour en savoir plus sur les espaces de noms Clojure.
Savez-vous s'il y a une différence à la fin entre (:use foo :only [bar])et (:require foo :refer [bar])? Cela semble étrange d'avoir deux façons de faire cela.
Overhink
10
On dirait que stackoverflow.com/a/10370672/69689 répond à ma question. En bref: (:require .. :refer ..)c'est une nouvelle façon de faire la même chose qui vous permet de déprécier efficacement :use, ce qui présente quelques inconvénients.
Refuser le
Bon donnant des exemples. J'adore les exemples, cela avait beaucoup de sens.
Astrid
35
Utiliser sure facilite les choses en ne vous obligeant pas à épeler l'espace de noms à chaque fois que vous voulez appeler une fonction, bien que cela puisse aussi faire un désordre en créant des conflits d'espace de noms. Un bon compromis entre «utiliser» et «exiger» est de n'utiliser que les fonctions d'un espace de noms que vous utilisez réellement.
par exemple:
(utilisez '[clojure-contrib.duck-streams: only (writer reader)])
ou mieux encore, spécifiez-le en haut du fichier dans la définition de l'espace de noms:
(ns com.me.project
(: use [clojure.contrib.test-is: only (deftest est run-tests)]))
Merci d'avoir inclus (jeu de mots) la (ns ...)syntaxe; J'avais cherché cela, mais tous les exemples que j'ai trouvés étaient simples (use ...).
paul
1
MISE À JOUR: cette méthode est maintenant obsolète en faveur de(require '[namepase :refer [var-name1 var-name2]])
Arthur Ulfeldt
@ArthurUlfeldt Vous voudrez peut-être mettre à jour votre réponse pour inclure (jeu de mots) ceci.
bfontaine
20
Comme cela a été mentionné, la grande différence est qu'avec (require 'foo), vous faites alors référence aux noms dans l'espace de noms de la lib comme ceci: (foo/bar ...)si vous le faites, (use 'foo)ils sont maintenant dans votre espace de noms actuel (quoi qu'il en soit et à condition qu'il n'y ait pas de conflit) et vous pouvez appeler eux aiment (bar ...).
Réponses:
require
charge les bibliothèques (qui ne sont pas déjà chargées),use
fait la même chose et fait référence à leurs espaces de noms avecclojure.core/refer
(vous avez donc également la possibilité d'utiliser:exclude
etc. comme avecclojure.core/refer
). Les deux sont recommandés pour une utilisation dansns
plutôt que directement.la source
Il est idiomatique d'inclure des fonctions externes avec
require
etrefer
. Vous évitez les conflits d'espace de noms, vous n'incluez que les fonctions que vous utilisez réellement / dont vous avez réellement besoin et vous déclarez explicitement l'emplacement de chaque fonction:Je n'ai pas besoin d'appeler cette fonction en la préfixant avec son espace de noms:
Si vous ne l'utilisez pas,
refer
vous devrez le préfixer avec l'espace de noms:Si vous choisissez à la
use
place, utilisez (à peu près) toujoursonly
:Sinon, vous incluez tout, ce qui en fait à la fois une opération inutilement volumineuse et très déroutante pour les autres programmeurs de trouver où se trouvent les fonctions.
En outre, je recommande vivement ce blog comme ressource pour en savoir plus sur les espaces de noms Clojure.
la source
(:use foo :only [bar])
et(:require foo :refer [bar])
? Cela semble étrange d'avoir deux façons de faire cela.(:require .. :refer ..)
c'est une nouvelle façon de faire la même chose qui vous permet de déprécier efficacement:use
, ce qui présente quelques inconvénients.Utiliser sure facilite les choses en ne vous obligeant pas à épeler l'espace de noms à chaque fois que vous voulez appeler une fonction, bien que cela puisse aussi faire un désordre en créant des conflits d'espace de noms. Un bon compromis entre «utiliser» et «exiger» est de n'utiliser que les fonctions d'un espace de noms que vous utilisez réellement.
par exemple:
ou mieux encore, spécifiez-le en haut du fichier dans la définition de l'espace de noms:la source
(ns ...)
syntaxe; J'avais cherché cela, mais tous les exemples que j'ai trouvés étaient simples(use ...)
.(require '[namepase :refer [var-name1 var-name2]])
Comme cela a été mentionné, la grande différence est qu'avec
(require 'foo)
, vous faites alors référence aux noms dans l'espace de noms de la lib comme ceci:(foo/bar ...)
si vous le faites,(use 'foo)
ils sont maintenant dans votre espace de noms actuel (quoi qu'il en soit et à condition qu'il n'y ait pas de conflit) et vous pouvez appeler eux aiment(bar ...)
.la source