2010-12-19 37 views
6

我正在嘗試互操作這個簡單的scala代碼,但我有一些麻煩。clojure/scala interop?

package indicators 

class DoubleRingBuffer(val capacity:Int=1000) { 
    var elements = new Array[Double](capacity); 
    private var head=capacity-1 
    private var max=0 

    def size():Int = { 
    return max+1 
    } 

    def add(obj:Double):Double = { 
    head-=1 
    if (head<0) head=capacity-1 
    return set(max+1,obj) 
    } 

    def set(i:Int,obj:Double):Double = { 
    System.out.println("HI") 
    if (i>=capacity || i<0) 
     throw new IndexOutOfBoundsException(i+" out of bounds") 
    if (i>=max) max=i 
    var index = (head+i)%capacity 
    var prev = elements(index) 
    elements(index)=obj 
    return prev 
    } 

    def get(i:Int=0):Double = { 
    System.out.println("size is "+size()) 
    if (i>=size() || i<0) 
     throw new IndexOutOfBoundsException(i+" out of bounds") 
    var index = (head+i)%capacity 
    return elements(index) 
    }  
} 

Clojure中,我這樣做

(import 'indicators.DoubleRingBuffer) 
(def b (DoubleRingBuffer. 100)) 
(pr (.size b)) ;;ERROR: No matching field found: size for class indicators.DoubleRingBuffer 
(pr (.get b 33)) ;;returns 0: should throw an index out of bounds error! 
(pr (.get b 100)) ;;throws index out of bounds error, as it should 

此外,我沒有得到任何輸出到控制檯!按照預期使用scala測試此代碼。這裏發生了什麼,我如何修復它,使clojure可以使用scala代碼?

回答

9

在REPL嘗試這些:

(class b)可能會告訴你這是indicators.DoubleRingBuffer

(vec (.getDeclaredMethods (class b)))將爲您提供在您的類中聲明的所有方法的向量,就像它是Java類一樣,因此您可以看到它們的簽名。

現在,使用這些方法名稱和參數,調用您在簽名中看到的方法。

我有一種感覺,問題在於Scala處理方法參數的默認值。

編輯:由於OP在評論中描述,它不是。

如果這不起作用,您可以嘗試將您的Scala字節碼反編譯爲Java,以瞭解DoubleRingBuffer類的外觀。

+0

謝謝!反編譯做了訣竅 - java代碼是完美的,所以最終這是我的增量構建工具的一些奇怪的錯誤 - 重新啓動,它按預期工作!順便說一句,我用http://java.decompiler.free.fr/,很棒的工具。 – josh 2010-12-19 14:33:40

+1

@josh:你也可以嘗試'scalac -print',它會打印出一個仍然是Scala語法的「desugared」版本,但是同構於Java,即所有高級的Scala特性都被刪除了。此外,還有'scalap',它像'javap'一樣工作,即反編譯'.class'文件。 – 2010-12-19 14:59:21

+0

@josh:很高興聽到它的作品! – 2010-12-19 16:35:24