使用expando元类添加curried闭包作为静态属性会丢失默认参数值

时间:2012-07-20 19:30:58

标签: groovy static-methods default-value expando

我在Groovy 1.8.6和2.0.0中都遇到过这种情况。

所以这些场景都按预期工作:

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。我无法在任何地方找到这种行为。我错过了什么吗?

1 个答案:

答案 0 :(得分:0)

如果问题仍然困扰着你,我认为这可能是一种解决方法,直到它在groovy trunk中修复。 python方式来讨论东西:

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') }