如何递归检查Groovy列表?

时间:2015-03-01 14:27:27

标签: groovy

我打算使用Groovy的inspect()方法来快速和脏对象持久性,但它没有像我预期的那样工作。更具体地说,如果我inspect()列表,则列表项不是inspect(),而是toString()。请考虑以下脚本:

class Foo {
    String inspect() { 'new Foo()' }
}

assert new Foo().inspect() == 'new Foo()'      // passes as expected
assert [new Foo()].inspect() == '[new Foo()]'  // fails

运行此脚本会产生以下输出:

Assertion failed:

assert [new Foo()].inspect() == '[new Foo()]'
        |          |         |
        |          |         false
        |          [Foo@3d52315f]
        Foo@3d52315f

        at test.run(test.groovy:6)

意味着永远不会调用inspect()实例上的Foo。这是一个Groovy错误吗?我正在使用Groovy 2.4.1进行测试。

1 个答案:

答案 0 :(得分:0)

尝试以下方式:

class Foo {
    String inspect() { 'new Foo()' }
}

assert new Foo().inspect() == 'new Foo()'      // passes as expected
assert [new Foo()]*.inspect().toString() == '[new Foo()]'

您需要对提供的列表中的每个元素调用inspect,然后使列表 inspectable 本身。但事实上,当涉及到docs时,这种行为似乎很奇怪。

这似乎是一个错误。从DefaultGroovyMethods来电inspect()被重定向到InvokerHelper。由于您传递了一个集合(列表)formatList方法将被调用。此方法迭代传递的列表并在同一个类中调用format。由于format不了解Foo,因此会将toString调用到传递的对象(第629行)。

以下示例显示了它的工作原理:

class Foo {
    String inspect() { 'new Foo()' }

    String toString() { 'new Foo()' }
}

assert new Foo().inspect() == 'new Foo()'     
assert [new Foo()].inspect() == '[new Foo()]'