[
https://issues.apache.org/jira/browse/GROOVY-11818?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=18048245#comment-18048245
]
Eric Milles edited comment on GROOVY-11818 at 12/29/25 4:06 PM:
----------------------------------------------------------------
Here are examples of using the reference:
https://github.com/apache/groovy/blob/2fc8212069c53713f8d07742629a57ad3b1cd207/src/test/groovy/org/codehaus/groovy/classgen/asm/AbstractBytecodeTestCase.groovy#L51
https://github.com/apache/groovy/blob/2fc8212069c53713f8d07742629a57ad3b1cd207/src/test/groovy/org/codehaus/groovy/classgen/asm/AbstractBytecodeTestCase.groovy#L117
was (Author: emilles):
Here is an example of using the reference:
https://github.com/apache/groovy/blob/2fc8212069c53713f8d07742629a57ad3b1cd207/src/test/groovy/org/codehaus/groovy/classgen/asm/AbstractBytecodeTestCase.groovy#L117
> For loop variable reference in anonymous classes yields unexpected results
> --------------------------------------------------------------------------
>
> Key: GROOVY-11818
> URL: https://issues.apache.org/jira/browse/GROOVY-11818
> Project: Groovy
> Issue Type: Bug
> Affects Versions: 3.0.25, 4.0.29
> Reporter: James Daugherty
> Priority: Minor
>
> I'm not sure if this is really a bug or design decision of Groovy that could
> be improved.
> Given this java code:
> {code:java}
> import java.util.*;
> import java.util.stream.*;
> class MyCommand {
> String filename;
> MyCommand(String filename) { this.filename = filename; }
> String getFilename() { return filename; }
> }
> interface MyFile {
> String getFilename();
> }
> List<MyCommand> commands = List.of(
> new MyCommand("testing1"),
> new MyCommand("testing2")
> );
> List<MyFile> files = new ArrayList<>();
> for (MyCommand cmd : commands) {
> MyFile file = new MyFile() {
> @Override
> public String getFilename() {
> return cmd.getFilename();
> }
> };
> files.add(file);
> }
> List<String> filenames = files.stream()
> .map(MyFile::getFilename)
> .collect(Collectors.toList());
> filenames
> {code}
> You can execute this code in jshell, and it will output:
> {code:java}
> | created class MyCommand
> | created interface MyFile
> commands ==> [MyCommand@34c45dca, MyCommand@52cc8049]
> files ==> []
> filenames ==> [testing1, testing2]
> filenames ==> [testing1, testing2] {code}
> But the equivalent in groovy code:
> {code:java}
> class MyCommand {
> String filename
> }
> interface MyFile {
> String getFilename()
> }
> List<MyCommand> commands = [new MyCommand(filename: 'testing1'),new
> MyCommand(filename: 'testing2')]
> List<MyFile> files = []
> for(MyCommand cmd in commands) {
> MyFile file = new MyFile() {
> String getFilename() {
> cmd.filename
> }
> }
> files.add(file)
> }
> files.collect{ it.filename }{code}
> will output
> {code:java}
> [testing2, testing2] {code}
> in Groovy 3.0.25 & 4.0.29 (tested in GroovyConsole). Adding a local
> variable to store the filename for that loop will fix the groovy code to
> return the same value as the Java equivalent. It seems the `cmd` variable is
> being reused on each iteration instead of creating a new reference. This
> causes code inside of the for loop for previous iterations to be updated to
> the new iteration value - which is inconsistent with Java's behavior.
> Note: using the closure iteration syntax (.each \{ }) does not have this same
> behavior as Java. Since both Java & the closure iteration syntax produce the
> same result, I think the for loop difference should be considered a bug in
> Groovy.
>
>
>
--
This message was sent by Atlassian Jira
(v8.20.10#820010)