A Simple Method to Override Host Data - blancas/eisen GitHub Wiki

In order to have any effect on the host program, Eisen code must be able to override data and functions, whose names it must be able to refer to. In this page we look at one simple way in which Eisen handles the visibility and overrides of host data and functions.

This method is based on access to the relevant vars in the host program, and changing them from user code (indirectly with alter-var-root). This is intended for programs that apply user code only at the start and are single-threaded. The advantage for the host program is that it requires a minimum of changes to accept customizations and extensions. The advantage for the user code is the automatic access to the host data for overrides, just by using the module eisen.user.

Access to Host Data

The host program can make its vars visible to the Eisen code, located in the eisen.user namespace, by calling functions host-name and host-module before any user code is evaluated.

host-name enters the given name, which may be qualified, into the eisen.user namespace. To illustrate this call we first define two vars in the host application.

(ns host.app)
(def foo 100)
(defn triple [n] (* n 3))

Now we call host-name on each name, which works as a reverse import.

(use 'blancas.eisen.core)
(host-name foo)
(host-name triple)

These names are now available in eisen.user.

(ns eisen.user)
foo
;; 100
(triple 5)
;; 15
(blancas.eisen.core/eisen= "triple 25")
;; 75

host-module enters all names from the given module into the eisen.user namespace. This function wraps a call to refer and will take options :exclude, :only and :rename. To illustrate this call we first define two vars in the host application.

(ns host.app)
(def top 99)
(defn square [n] (* n n))
(defn trace [] nil)

Now we call host-module on host.app to make its vars visible from eisen.user.

(use 'blancas.eisen.core)
(host-module host.app)

These names are now available in eisen.user.

(ns eisen.user)
top
;; 99
(square 5)
;; 25
(blancas.eisen.core/eisen= "square 5")
;; 25

Overriding Host Data

The user code can override host vars by calling setq and setv, either within a function or as s top-level (naked) expressions.

setq sets the value of a host var to the value of an expression. The syntax is:

setq name = expression

Follwing with the example above, we may change the value of top.

(blancas.eisen.core/eisen= "setq top = 101")
;; 101
top
;; 101

setv sets the value of a host var to the value of a local var. The syntax is:

setv name = var

Use this construct to override a function. In the example above, we can override the function trace.

(blancas.eisen.core/eisen= "fun show =  println \\"user code enabled\\"")
(blancas.eisen.core/eisen= "setv trace = show")

Running trace from its original namespace.

(ns host.app)
(trace)
;; user code enabled