8

in the :constructors map and subsequent -init definitions, how do I represent a varargs constructor (assuming the superclass has multiple constructors of which one is varargs) ?

Abimaran Kugathasan
  • 31,165
  • 11
  • 75
  • 105
Hendekagon
  • 4,565
  • 2
  • 28
  • 43

2 Answers2

2

Since varargs are essentially syntax sugar for Object arrays, you could just use "[Ljava.lang.Object;" as the type of constructor's parameter.

Here's some sample code:

(ns t.vtest
  (:gen-class
   :implements   [clojure.lang.IDeref]
   :init init
   :state state
   :constructors {["[Ljava.lang.Object;"] []}))
   ;;                                      ^-----------------------
   ;; You should put "[Ljava.lang.Object;" for superclass varargs constructor here
   ;; I left it blank for the sake of working example 

(defn -init
  [args]
  (println "first element of args" (aget args 0) "total elements" (alength args))
  [[] (into [] args)])

(defn -deref
  [this]
  (.state this))

and that's how it looks in REPL

user=> @(t.vtest. (into-array Object ["A" "B" 1 2]))
first element of args A total elements 4
["A" "B" 1 2]
spariev
  • 399
  • 2
  • 5
  • It doesn't solve problem stated in question. Rather than defining a vararg method it generates method accepting array. This is not the same. The difference is that the vararg is flagged by special ACC_VARARGS opscode in generated byte-code which clojure don't support at the moment. – Lambder Sep 11 '13 at 09:43
1

Since clojure don't support it at the moment you need to patch it with: https://groups.google.com/forum/#!topic/clojure/HMpMavh0WxA.

And use it with new meta tag:

(ns t.vtest 
  (:gen-class 
   :implements   [clojure.lang.IDeref]
   :init init
   :state state
   :constructors {^:varargs ["[Ljava.lang.Object;"] []} 
  ))
Lambder
  • 2,953
  • 1
  • 26
  • 20