Reputation: 4913
I am trying to understand the following code snippet following site.
<% refChanges.getCommits(repository).each { commit -> %>
- ${commit.author.name} | ${commit.displayId} | ${commit.message} | ${commit.authorTimestamp}
<% } %>
The script is using a getCommits method, but when I look at the documentation for the RefChange interface I do not see any such method.
I consider myself an expert Java developer, but I have no workable knowledge in Groovy, so I assume that I am misunderstanding Groovy or the BitBucket documentation (or both).
Upvotes: 0
Views: 418
Reputation: 9895
In Groovy it's possible to add methods to a class or interface at run-time via meta-programming. Since the RefChange
interface does not include getCommits()
, it must be that the method is being added after-the-fact. Based on their example code, it looks like they're using the meta-class.
For example, in Groovy the Collection
interface gets the method findAll()
(along with many other methods). I can confirm this as follows:
assert Collection.metaClass.metaMethods*.name.contains('findAll') == true
The code above grabs the names of all the meta methods and then uses contains()
to see if a match is found. You can confirm the same for getCommits()
in a similar way:
assert Collection.metaClass.metaMethods*.name.contains('getCommits') == true
Note that I specified Collection
rather than RefChange
because refChanges
is a Collection
of RefChange
. And so I think Atlasssian stuck getCommits()
into Collection
as a convenience method.
To understand what's going, I'll remove the templating code:
refChanges.getCommits(repository).each { commit ->
"${commit.author.name} | ${commit.displayId} | ${commit.message} | ${commit.authorTimestamp}"
}
getCommits()
returns a Collection
of com.atlassian.bitbucket.commit.Commit
.Closure
repeatedly; each time with an element of the Collection
.each(Closure)
is a GString. Basically the expressions within the ${...}
are evaluated and the whole thing is concatenated into a String
.Upvotes: 2