ikitommi / dynaload

The dynaload logic from clojure.spec.alpha as a library

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

dynaload

Dynaload functionality blatantly stolen from clojure.spec.alpha.

Why

It's often useful to make libraries light-weight and transitive dependencies optional. For example, clojure.spec.alpha makes test.check optional in both the Clojure and ClojureScript implementations. This project extracts that logic and packages it as a library.

Usage

This library exposes two namespaces, one for Clojure (borkdude.dynaload-clj) and one for ClojureScript (borkdude.dynaload-cljs). Each namespace exposes one public var, dynaload. In Clojure dynaload is a regular function, in ClojureScript it's macro. Both versions return a delay that will either contain a value or will throw upon deref. It lets you dynamically refer to a var that may or may not be there. In Clojure it will require the namespace for you and throw if the namespace is not there. In ClojureScript you will have to require the namespace manually before deref, since ClojureScript namespaces cannot be loaded dynamically (outside of a REPL).

Consider this example from examples/sci.cljc

(ns example.sci
  (:require
   #?(:clj  [borkdude.dynaload-clj  :refer        [dynaload]]
      :cljs [borkdude.dynaload-cljs :refer-macros [dynaload]])))

(def eval-string (dynaload 'sci.core/eval-string))

(println (@eval-string "(+ 1 2 3)"))

First we run this without having the sci library on the classpath.

On the JVM:

$ clojure example/sci.cljc
Syntax error (FileNotFoundException) compiling at (example/sci.cljc:8:1).
Could not locate sci/core__init.class, sci/core.clj or sci/core.cljc on classpath.

Full report at:
/var/folders/2m/h3cvrr1x4296p315vbk7m32c0000gp/T/clojure-3838719710831994824.edn

ClojureScript:

$ plk example/sci.cljc
Execution error (Error) at (<cljs repl>:1).
Var sci.core/eval-string does not exist, sci.core never required

And now we load it with sci on the classpath.

JVM:

$ clj -Sdeps '{:deps {borkdude/sci {:mvn/version "0.1.0"}}}' example/sci.cljc
6

ClojureScript:

$ plk -Sdeps '{:deps {borkdude/sci {:mvn/version "0.1.0"}}}' -e "(require '[sci.core])" example/sci.cljc
6

Again, note: in ClojureScript we had to require sci manually, whereas in Clojure it was required for us.

Test

$ script/test

License

Copyright © 2020 Michiel Borkent

Distributed under the EPL License. See LICENSE.

This project is based on code from:

About

The dynaload logic from clojure.spec.alpha as a library

License:Eclipse Public License 1.0


Languages

Language:Clojure 87.5%Language:Shell 12.5%