Проблемы с пространством имен Clojure и Lein при использовании nREPL
У меня много "веселья", пытаясь понять, почему ниже не будет работать. После запуска сеанса nREPL в src
каталог моего lein
Проект, я сделал следующее:
user> (require 'animals.core)
nil
user> (animals.core/-main)
"Welcome to Animals!"
nil
user> (require 'animals.animal)
nil
user> (extends? animals.animal/Animal animals.animal/Dog)
CompilerException java.lang.RuntimeException: No such var: animals.animal/Dog, compiling:(NO_SOURCE_PATH:1:1)
Читая учебник Lein, я понимаю, что должен разместить свой источник так:
- src/
|____ animals/
|_______ core.clj
|_______ animal.clj
Где содержимое животного ниже выглядит так:
(ns animals.animal)
(defprotocol Animal
"A protocol for animal move behavior."
(move [this] "Method to move."))
(defrecord Dog [name species]
Animal
(move [this] (str "The " (:name this) " walks on all fours.")))
(defrecord Human [name species]
Animal
(move [this] (str "The " (:name this) " walks on two legs.")))
(defrecord Arthropod [name species]
Animal
(move [this] (str "The " (:name this) " walks on eight legs.")))
(defrecord Insect [name species]
Animal
(move [this] (str "The " (:name this) " walks on six legs.")))
Почему исключение во время выполнения является результатом попытки оценить Dog
при оценке Animal
не привело к ошибке? Как можно поступить правильно?
1 ответ
Animal
это протокол. Протокол имеет связанный Var в пространстве имен, в котором он определен. Именно через этот Var можно ссылаться на протокол.
По сравнению, Dog
это запись. Записи являются просто классами и не имеют соответствующих им переменных. (Ну, есть фабричные функции, хранящиеся в Vars, но вы не можете ссылаться на саму запись через эти фабричные функции.) Таким образом, чтобы ссылаться на запись, вам нужно использовать другой синтаксис: animals.animal.Dog
,