My log (with robert-hooke) does not work properly with tools.namespace / refresh, why?

EDIT: It turned out that I used requireinstead :requirein the namespace declaration. C :require, tools.namespace updates the log namespace and the problem goes away. However, I'm still curious that the expression (eval `(var ~(symbol "A/func")))does not work in the situation described below (that is, if B is not updated below).

Summary: I use tools.namespace. If I have the spaces A and B names and B do (eval `(var ~(symbol "A/func")))and (tools.namespace/refresh)and code execution, it works. But if I made changes to A, make (tools.namespace/refresh)it so that only A is updated, and then running this expression, you will get an error: Cannot resolve var: A/func in this contextalthough it A/funcexists. Why?

Longer version:

In my project, I have a registration module / namespace that uses robert-hooke (see below). I use tools.namespace to reload my code when making changes.

The problem is this: when I want the journal (my journal is currently just printing) something, I list the functions that I want to register in my journal namespace and do it (t.n/refresh). It works. But if I make changes to the namespaces that contain the functions that I want to register and do (t.n/refresh)without making changes to the log namespace, the log no longer works (for updated functions). As soon as I make changes to the log, so that it is also updated using tools.namespace, it starts working again.

, , vars , , . , .

. add-logging-wrappers , .

(eval `(var ~(symbol "sv/register-damage"))) add-logging-wrappers, , . , Cannot resolve var: sv/register-damage in this context.

(ns game.logging
  (require [robert.hooke :as rh]
           [clojure.pprint :as pp]
           [game.server.core :as sv]
           [game.client.core :as cl]
           [game.math :as math]
           (game.common [core-functions :as ccfns]
                        [graphics :as gfx])
           (game.server [pathfinding :as pf]))
  (:use [game.utils]))

(defn log-println [name type object]
  (println (str (current-thread-name) " // " name " " type ":\n"
                (with-out-str
                  (pp/pprint object)))))

(defn print-output [name f & args]
  (let [result (apply f args)]
    (log-println name "output" result)
    result))

(defn print-input [name f & args]
  (log-println name "input" args)
  (apply f args))

(defn print-call [name f & args]
  (println (str (current-thread-name) "//" name))
  (apply f args))

(defmacro make-name-var-list [fn-list]
  `[~@(for [fn fn-list]
        [(str fn) `(var ~fn)])])

(defmacro defloglist [name & fns]
  `(def ~name (make-name-var-list [~@fns])))

(defn add-hooks [name-vars & wrappers]
  (when (seq wrappers)
    (doseq [[name var] name-vars]
      (rh/add-hook var (partial (first wrappers) name)))
    (recur name-vars (next wrappers))))

(defn get-ns-name-vars [ns-sym]
  (-> (the-ns ns-sym) (#(.name %)) ns-interns))

(defn add-hooks-to-ns [ns-sym & wrappers]
  (apply add-hooks (get-ns-name-vars ns-sym) wrappers))

(defloglist log-both 
  sv/distribute-exp     ;; <--- things to log
  sv/register-damage
  sv/give-exp)

(defloglist log-input)

(defloglist log-output)

(defn add-logging-wrappers []
  (dorun (->> (all-ns) (map #(.name %)) (mapcat ns-interns) (map second)
              (map rh/clear-hooks)))
  (add-hooks log-both print-output print-input)
  (add-hooks log-input print-input)
  (add-hooks log-output print-output))
+4

Source: https://habr.com/ru/post/1526443/


All Articles