2012-07-20 11 views
6

我在Groovy 1.8.6和2.0.0中都遇到了這個問題。使用expando元類添加curried closure作爲靜態屬性失去默認參數值

所以這些方案預期的所有工作:

def ay = { one, two=[:] -> [one, two] } 
def be = { one, two, three=[:] -> [one,two,three] } 
def ayprime = ay.curry('PRIME') 
def beprime = be.curry('PRIME') 
def beprimer = be.curry('PRIME', 'PRIMER') 

assert ay(1,2) == [1,2] 
assert ay(1) == [1,[:]] 
assert be(1,2,3) == [1,2,3] 
assert be(1,2) == [1,2,[:]] 

assert ayprime(1) == ['PRIME', 1] 
assert ayprime() == ['PRIME', [:]] 
assert beprime(1,2) == ['PRIME', 1, 2] 
assert beprime(1) == ['PRIME', 1, [:]] 
assert beprimer(1) == ['PRIME', 'PRIMER', 1] 
assert beprimer() == ['PRIME', 'PRIMER', [:]] 

至於做這個的:

class Klass { 
    static def smethod = { one, two=[:] -> [one, two] } 
} 
assert Klass.smethod(1,2) == [1, 2] 
assert Klass.smethod(1) == [1, [:]] 

也適用,符合市場預期:

Klass.metaClass.static.aymethod << ay 
assert Klass.aymethod(1) == [1, [:]] 

默認參數不安的關閉仍然存在於Klass

然而,這失敗

Klass.metaClass.static.ayprimemethod << ayprime 
assert Klass.ayprimemethod() == ['PRIME', [:]] 

正是如此:

assert Klass.ayprimemethod() == ['PRIME', [:]] 
      |    | 
      [PRIME, null] false 

,同樣,失敗:

Klass.metaClass.static.beprimermethod << beprimer 
assert Klass.beprimermethod() == ['PRIME', 'PRIMER', [:]] 

正是如此:

assert Klass.beprimermethod() == ['PRIME', 'PRIMER', [:]] 
     |    | 
     |    false 
     [PRIME, PRIMER, null] 

使用curried閉包時,默認參數值直接起作用,但當閉包分配爲Klass的靜態成員時會丟失。

這個好像是就像一個bug。我無法在任何地方找到這種行爲。我錯過了什麼嗎?

+0

我看到了同樣的行爲。我也測試了它作爲一個類實例方法(所以它可以通過'Klass.metaClass.ayprimemethod << ayprime; assert new Klass()。ayprimemethod()== ['PRIME',[:]]')來測試,並發現相同的問題。看起來你應該[在JIRA中提交一個bug](http://jira.codehaus.org/secure/BrowseProject.jspa?id=10242)。 – OverZealous 2012-07-21 04:52:40

+0

完成。 http://jira.codehaus.org/browse/GROOVY-5621 – 2012-07-23 15:37:07

+0

感謝您對currying的解釋:) – 2012-07-23 19:49:37

回答

0

如果問題仍然困擾着你,我認爲這可能是一個解決方法,直到它在groovy trunk中得到修復。蟒蛇的方式來咖喱東西:

def ayprime = { x -> x ? ay('PRIME', x) : ay('PRIME') } 
def beprime = be.curry('PRIME') 
def beprimer = { x -> x ? be('PRIME', 'PRIMER', x) : be('PRIME', 'PRIMER') }