Программно переопределить функции - PullRequest
0 голосов
/ 26 января 2020

Я сейчас нахожусь в процессе создания инструмента, который должен изменять все функции в другом пространстве имен, и запускаю «основную» функцию в этом (другом) пространстве имен. Почти как издевательство в юнит-тестировании, но для другой цели. Первым шагом к этому является переопределение функций из другого пространства имен. В первом листинге показан код, который работает, где я явно называю функцию, подлежащую замене.

(ns one)
(defn a-fun []
  (println "original"))

(defn caller []
  (a-fun))

(ns two)

(with-redefs [one/a-fun #(println "replaced")]
  (one/caller))
;; replaced
;; nil

Следующим шагом является программное получение функций из другого пространства имен. Это где я столкнулся с стеной. Я много экспериментировал с ns-publics, но пока не повезло. Поэтому я пытаюсь решить проблему. И проблема в том, что замена функции не работает. Вывод должен печатать «заменено», а не «оригинально».

(ns two)
(def target (ns-resolve 'one (symbol "a-fun")))
(def caller (ns-resolve 'one (symbol "caller")))
(with-redefs [target #(println "replaced")]
  (caller))
;; original
;; nil

Теперь, #'two/target показывает #'one/a-fun, когда я оцениваю его в repl. Я могу позвонить one/a-fun, введя ((ns-resolve 'one (symbol "a-fun"))) в ответ, так что я не понимаю, какая часть не работает.

Я прошел много документации сегодня, и я не совсем все ближе.

1 Ответ

0 голосов
/ 26 января 2020

Вы можете попробовать использовать with-redefs-fn примерно так:

(defn p [] "old")

(with-redefs-fn
  {(ns-resolve *ns* 'p) #(println "new")}
  (fn []
    (p)))
;; => new

Это означает, что тело with-redefs-fn должно быть функцией, которая использует ваши переопределенные переменные.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...