Add constructor to deftype created class
Asked Answered
R

2

11

For the purposes of interoperability with Java, I need a class that has a nullary constructor that performs initialization. Objects of this class need to have something resembling mutable java fields (namely, the object represents the backend of a game, and needs to keep game state).

deftype does everything I want to do except provide a nullary constructor (since I'm creating a class with fields).

I don't need the fields to be publicly readable, so I can think of 4 solutions:

Use gen-class; I don't want to do this if I can avoid it.
Somehow encoding private member variables outside of the knowledge of deftype; I've been told this can't be done.
Writing a modified deftype that also creates a nullary constructor; frankly I don't know clojure well enough for this.
Taking the class created by deftype and somehow adding a new constructor to it.

At the end of this, I need to have a Java class, since I will be handing it off to Java code that will be making a new object from the class.

Are any of the solutions I suggested (or any that I haven't thought of) other than using gen-class viable?

Rushy answered 29/6, 2011 at 2:30 Comment(2)
Seems that constructor creation is deep inside the java code of clojure. So modifying the deftype itself sounds bit hard and a bit bad idea.Smokechaser
how will the fields be accessed and the instance generated yourClass.newInstance() and reflection? SO maybe knowing more of the Java side usage for the generated class will help otherwise i'm bit afraid it's time for gen-class :(Smokechaser
W
3

There's absolutely no shame in, where appropriate, writing a dash of Java if your Java interop requirements are simultaneously specific and unshakable. You could write a Java class with a single static factory method that returns an instance of the deftype class and that does whatever initialization/setup you need.

Alternatively, you can write a nullary factory function in Clojure, and call that directly from Java all day long.

In any case, neither deftype nor defrecord are intended to be (or will they ever be) fully-featured interop facilities. gen-class certainly comes the closest, which is why it's been recommended.

Wring answered 30/6, 2011 at 11:4 Comment(0)
H
2

I'd suggest just writing the object in Java - for Java-like objects with mutable fields it will probably be more elegant, understandable and practical.

I've generally had pretty good results mixing Java and Clojure code in projects. This seems like one of those cases where this might be appropriate. The interoperability is so good that you barely have any extra complexity.

BTW - I'm assuming that you need a nullary constructor to meet the requirements of some persistence library or something similar? It seems like an odd requirement otherwise. If this is the case then you may find it makes sense to rethink your persistence strategy..... arbitrary restrictions like this always seem like a bit of a code smell to me.

Hygrometry answered 30/6, 2011 at 21:9 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.