You need to replace pr with print-method inside the do. pr doesn't
accept the writer argument.
That'll only take are of printing, though; I'm not sure if there is a
way to override .toString on a deftype, since I believe that's a
method of the Object class and not an interface/protocol... :-(
All the best,
Michał
(defmethod clojure.core/print-method ::Piece
[piece writer]
(.write writer (str (:number piece) (:letter piece)) 0 2))
Extending Piece to provide a str method can replace that ugly bit in
the middle.
-m
But how would one go about that? str calls .toString on its arguments,
which is in turn a method of Object, thus not present in any
interface, whereas deftype / extend only allow one to implement
interface or protocol methods...
Sincerely,
Michał
deftype expects method definitions *not* to accept an explicit "self"
argument. You need to do something like this instead:
(deftype Piece [#^int number #^char letter]
Comparable
(compareTo
[x]
(let [c1 (compare number (:number x))]
(if (zero? c1) (compare letter (:letter x)) c1))))
Note that own fields can be accessed by name. If you do need a "self"
argument, you can create an implicit self available to all method
bodies by passing
:as some-symbol
to the deftype right after the fields vector.
Sincerely,
Michał
print-dup is just another multimethod, so an implementation of that
can be defined. Obviously deserialisation with read will have no
chance of working in the context of code which doesn't know the
relevant deftype, but when the deftype is known, one could perhaps use
#= for it:
(read-string "#=(Piece 1 \A)")
Sincerely,
Michał
On Sun, Mar 21, 2010 at 08:43:10PM +0100, Michał Marczyk wrote:
> But how would one go about that? str calls .toString on its arguments,
> which is in turn a method of Object, thus not present in any
> interface, whereas deftype / extend only allow one to implement
> interface or protocol methods...
user=> (deftype Xyz []
Object
(toString
[]
"This is a Xyz!"))
#'user/Xyz
user=> (str (Xyz))
"This is a Xyz!"
The docstring of deftype says protocol, interface or Object.
Sincerely
Meikel
So it does. (My, do I feel silly now.) Thanks!
Sincerely,
Michał
One more thing to know about print-method for deftype: The deftype
macro generates a default implementation for deftype. Defining your
own replaces the default version, which in most situations is just fine.
However, there is a situation that requires more effort. Suppose you
have a family of types for which you want to implement a common print-
method. The obvious approach for any multimethod would be to declare
all those types as derived from some parent (a namespace-qualified
keyword will do, there is no need to have any implementation for a
parent type) and have a print-method implementation for the parent.
The problem is just that the type's default implementation will be
used in preference to the shared one. The solution is to remove the
default method using remove-method.
Konrad.