LINUX.ORG.RU

Видимость extend-type для протокола.

 


0

1

По мотивам предыдущей темы хочу полюбопытствовать как оно работает. Имеется модуль А, содержащий

(defprotocol MyProt
  (bar [a b]))

(defn foo
...
  (bar ...)
...)

Имеется модуль Б, использующий модуль А следующим образом

(extend-type clojure.lang.IPersistentMap
  MyProt
  (bar [a b] ...

(defn what-else
...
  (foo ...)
...)

Так вот. Если загрузить модуль Б в nREPL и вызвать функцию what-else, то сыпется на следующем

No implementation of method: :bar of protocol: #'user/MyProt found for class: clojure.lang.PersistentArrayMap

Но если загрузить в nREPL ещё и модуль А, не меняя при этом область видимости, и повторить вызов what-else, то всё замечательно заработает.
lein test естественно тоже валится на этом.

Вопрос: как так устроен этот чудо extend-type, что твориться такая ересь?

В общем проблема в том, что описанная функция what-else выполняет своё тело в контексте модуля А, в котором протокол ничего не знает о совершенных extend-type в модуле Б и соответственно не может ничего найти. Решено вынесением defprotocol в модуль Б и передачей функции bar как параметр в функцию what-else. nREPL похоже всё кидает в общий котёл, пытаясь резолвить символы только на стади C-c C-l.

proofit404
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.