How to require dependencies in Clojure? - clojure

I have two questions regarding dependencies in Clojure project.
Is there something like :dev-dependencies or :test-dependencies so that I don't have to download them all on lein run? So until I run my tests I don't need to have these extra libraries.
Can I load dependencies in one file and require this one file in an another file? I'd like to have something similar to:
; dependencies.clj
; ...
(:require [clj-http.client :as client]
[clj-http.fake :refer :all]
[clojure.test :refer :all]))
; some-file.clj
; ...
(:require [dependencies :refer :all[)

1) Yes, Leiningen offers profiles for just these purposes
2) No, referals from one namespace are not "inherited" between namespaces. You can't express "I want to refer to everything in this namespace, that some other namespace refers"

Regarding your point 2, Potemkin can help you do this. Potemkin is especially useful if you have several namespaces implementing the functionality of a library, but then want to present a single namespace to users of the library.

Related

What is the difference between core.clj and inope.clj in a clojure project?

What is the difference between core & inope?
I have a very brief idea that core is like the main equivalent in Java. And inope is like an interface between java and clojure, although I dont understand the purpose of inope entirely.
I found this in a project and this is my understanding:
inope.clj is used for writing java clojure interoperable functions.
The namespace contents imply that it functions like core.clj here.
in this inope.clj file, they have imported dependencies and defined java-clojure interoperable functions in gen-class as such :
(ns prject-avon.inope
(:require [prject-avon.ioutil :as utl]
[aero.core :as aero-core :refer (read-config)]
[clojure.java.data :as clj-data]
[malli.core :as m]
[malli.util :as mu]
[malli.instrument :as mi]
[malli.error :as me]
[malli.json-schema :as json-schema]
(:gen-class
:methods [ ^{:static true} [validateData [Object String] Boolean]
]))
<Functions are defined here>
Those are just names, there's no significance to them. In particular, I've never heard of inope myself. The only way you can reliably judge is by the namespace's contents and their usage. It's also very possible that a single namespace contains all sorts of unrelated stuff.

Why do I get IllegalAccessError when trying to import a protocol or record from another namespace

I have a file in my project where I define a few protocols and records (defprotocol and defrecord).
I'm trying to use them in a different file/namespace like this:
(ns myapp.core
(:require [myapp.protocols :refer [SomeProtocol]]))
This causes an Execution error (IllegalAccessError) at .... Does anyone know why?
btw, doing :refer :all does work but I don't want to bring in several unneeded symbols into the namespace.
thanks

How to nest require in Clojure?

Suppose I have a namespace parent.namespace, which has two children child1.namespace and child2.namespace, i.e., both require parent.namespace. Both child1.namespace and child2.namespace require some package (:require [some.package :refer [stuff]]). Is there a way to require this package only once in the parent.namespace and then require only parent.namespace in both children without having to require some.package in each child separately?
No, there is no nesting or inheritance behavior like you are suggesting. Each child namespace must look like so:
(ns child1.namespace
(:require
[parent.namespace :as parent]
[some.package :refer [stuff]))

How to require a namespace programmatically

I'm working on a Liberator project in Clojure. I've defined a series of routes which return JSON data computed by logic in some other namespace. I would like to be able to change the namespace that implements the logic programmatically so I can do something like this:
JAVA_OPTS='-DgameLogicNamespace=foo.logic.mock' lein ring server-headless 8080
I am currently doing it like this:
(ns foo.routes
(:require [compojure.core :refer :all]
[liberator.core :as lib :refer [defresource request-method-in]]
[liberator.representation :refer [ring-response]]))
(require
(vec
(cons (symbol (System/getProperty "gameLogicNamespace" "foo.logic.real"))
'[:as logic])))
This works, but feels a bit clunky. Is there an idiomatic way to accomplish what I want?
One of my main motivations is actually for unit testing routes with mock data, so if there's a nice solution for providing the mock logic only in tests (and not as a JVM system property), suggestions are welcome.
One of my main motivations is actually for unit testing routes with mock data, so if there's a nice solution for providing the mock logic only in tests (and not as a JVM system property), suggestions are welcome.
If you haven't already, take a look at ring-mock for some nice utilities to generate mock requests to test your Ring handlers.
If you're interested in providing mock versions of functions that provide the implementation of your application logic during unit tests, consider using with-redefs; it's pretty much custom-made for this purpose.
(ns my-app.handlers-test
(:require [clojure.test]
[my-app.handlers :as h]
[my-app.logic :as l]
[ring.mock.request :as r]))
(deftest test-simple-handler
(with-redefs [l/my-complicated-logic #(update-in % [:a] inc)]
(is (= {:a 2}
(h/my-handler (r/request :post "/foo" {:a 1}))))))

In Clojure 1.4 what is the use of refer within require?

What advantage does using :refer in :require have over using :only in :use? Are the following synonymous?
(ns so.example (:use [my.lib :only [function]]))
and
(ns so.example (:require [my.lib :refer [function]]))
Main idea of adding :refer to :require is to get rid completely of :use, leaving only one operator to load other packages. You can emulate existing :use with (:require [my.lib :refer :all])...
yes, they are equivalent,
:refer and :require are the basic operations required to build namespaces. :use is more convienient
:require causes classes to be loaded
:refer adds things to the name space which is really just a map (actually a couple of maps)
:use is :refer + :require
as much is it may look like it, there really is no magic to namespaces
if you make a namespace like this
(ns so.example (:use my.lib))
the equivalent with :require would be:
(ns so.example (:require [my.lib :refer [function1 function2 function3
list every function in example
here and remember to keep it
up to date ]]))
As of the 1.4.0 release, there's no longer a good reason to use use. Use require :refer instead. From the Clojure 1.4.0 changelog: "require can now take a :refer option. :refer takes a list of symbols to refer from the namespace or :all to bring in all public vars."
(from https://8thlight.com/blog/colin-jones/2010/12/05/clojure-libs-and-namespaces-require-use-import-and-ns.html)