Skip to content

Commit

Permalink
Skip redefinition of defstate when active
Browse files Browse the repository at this point in the history
  • Loading branch information
Arnout Roemers committed Jul 24, 2020
1 parent 9261f3d commit 080b231
Show file tree
Hide file tree
Showing 4 changed files with 25 additions and 6 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
# Change Log

## 1.0.3

### Added

- Trying to redefine an active (i.e. realized) `defstate` is skipped and yields a warning.


## 1.0.2

### Fixed
Expand Down
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,8 @@ Therefore the above can also be written as follows:
```

Users of [mount](https://github.com/tolitius/mount) or [mount-lite](https://github.com/aroemers/mount-lite) will recognize above syntax.
Trying to redefine a `defstate` which is active (i.e. realized) is skipped.

The `defstate` macro fully supports metadata on the name, a docstring and an attribute map.
Note that this metadata is set on the var.
If you want metadata on a State, you can use **a `:meta` expression** in the body of the `state` macro, or use Clojure's `with-meta` on it.
Expand Down
2 changes: 1 addition & 1 deletion project.clj
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
(defproject functionalbytes/redelay "1.0.2"
(defproject functionalbytes/redelay "1.0.3"
:description "Clojure library for first class lifecycle-managed state."
:url "https://github.com/aroemers/redelay"
:license {:name "EPL-2.0 OR GPL-2.0-or-later WITH Classpath-exception-2.0"
Expand Down
20 changes: 15 additions & 5 deletions src/redelay/core.clj
Original file line number Diff line number Diff line change
Expand Up @@ -87,9 +87,15 @@
(recur qualifiers (rest exprs) qualifier (update qualified qualifier (fnil conj []) expr))))
qualified)))

(declare state?)

(defn- skip-defstate? [ns name]
(let [state (some-> (ns-resolve ns name) deref)]
(and (state? state) (realized? state))))

;;; Public API

(defn state*
(defn state*
"Low-level function to create a State object. All keys are optional.
The `:start-fn` value must be a 0-arity function. The `:stop-fn`
value must be a 1-arity function. The `:meta` value must be a map."
Expand Down Expand Up @@ -131,12 +137,16 @@
"Create a State object, using the optional :start, :stop and :meta
expressions, and bind it to a var with the given name in the current
namespace. Supports metadata on the name, a docstring and an
attribute map."
attribute map. Trying to redefine an active (i.e. realized) defstate
is skipped."
{:arglists '([name doc-string? attr-map? body])}
[name & exprs]
(let [[name exprs] (name-with-exprs name exprs)]
`(def ~name
(state ~@exprs :name ~(symbol (str *ns*) (str name))))))
(if (skip-defstate? *ns* name)
(binding [*out* *err*]
(println "WARNING: skipping redefinition of active defstate" name))
(let [[name exprs] (name-with-exprs name exprs)]
`(def ~name
(state ~@exprs :name ~(symbol (str *ns*) (str name)))))))

;;; Default management.

Expand Down

0 comments on commit 080b231

Please sign in to comment.