Groovy+Xml(その4:XmlParserのサンプルの謎)

Groovy

XmlParserのサンプルコードとして以下のページが参考になる。

Updating XML with XmlParser - Groovy - Codehaus

さて、このコードの中でずっと疑問だった箇所がある。コードの41行めからを取り上げて話をしたい。

以下のコードを実行すると

def groceries = root.category.findAll{ it.@type == 'groceries' }.item[0]
groceries.each { g ->
    g.value = 'Luxury ' + g.text()
}

なぜかgroceries.each()の処理が2回実行される。

すぐ上の処理で...item[0]としているので、item要素の1つ目が取得されるのでeachは1回しか実行されないはずなのに。なんど読んでもこのコードがわからなかった。

さっき散歩している間にふっと気づいた。先のコードは以下のように書き換えられる。

def groceries = root.category.find{ it.@type == 'groceries' }.item
groceries.each { g ->
    g.value = 'Luxury ' + g.text()
}
def groceries = root.category.findAll{ it.@type == 'groceries' }[0].item
groceries.each { g ->
    g.value = 'Luxury ' + g.text()
}
// これはかなり苦し紛れ
def groceries = (root.category.findAll{ it.@type == 'groceries' }*.item)[0]
groceries.each { g ->
    g.value = 'Luxury ' + g.text()
}

最後に添字指定するのは誤解を生む表現で、サンプルとして適切じゃないんじゃないかなと思ったよ。配列に対して配列自身のメソッド以外を実行しようと場合には、配列内の全要素に対して実行された結果が返ってくることに注意。

Groovy