(ns protocols-records-learning.core)
(defprotocol Hit-points
"Able to be harmed by environment interaction."
(hit? [creature hit-roll] "Checks to see if hit.")
(damage [creature damage-roll] "Damages target by damage-roll, negated by per-implementation factors.")
(heal [creature heal-roll] "Heals creature by specified amount."))
(defrecord Human [ac, health, max-health]
Hit-points
(hit? [creature hit-roll] (>= hit-roll ac))
(damage [creature damage-roll] (if (pos? damage-roll) (Human. ac (- health damage-roll) max-health)))
(heal [creature heal-roll] (if (pos? heal-roll)
(if (>= max-health (+ heal-roll health))
(Human. ac max-health max-health)
(Human. ac (+ heal-roll health) max-health)))))
(def ryan (atom (Human. 10 4 4)))
(defn hurt-ryan
"Damage Ryan by two points."
[ryan]
(swap! ryan (damage 2)))
Leads to error:
Exception in thread “main” java.lang.IllegalArgumentException: No single method: damage of interface: protocols_records_learning.core.Hit_points found for function: damage of protocol: Hit-points (core.clj:34)
Can somebody explain this error, and what is causing it, and how to properly change the atom?
This should work.
Note, the removed pair of parens around damage. The error message is a clunky try to tell you that Clojure didn’t find a version of damage with the arity of 1. The parens around damage try to do exactly that: call damage with one argument (the 2).
Improvement of the error messages is an ongoing task, which has arrived at protocols, yet.