okay, so let's solve this from the beginning,
This syntax refers to looping over a RECORD, not an ARRAY. for looping over arrays, you would have:
for rec: std.iterArray(array) {
For arrays, you do have the file name as a string, in this case rec.file
Now, you are wondering the file names for the PORTS of the RECORD:
myRecord={}
for name, port: inRecord {
foo=SomeComponent(input=port, @name="some_"+name)
myRecord[name]=foo.output1
}
The simple answer would be, that Anduril provides you with an environment, where you don't have to care about the file names, since the ports are connected through an internal mechanism, relieving you from all the troubles of file names, and if you want to know the file names, maybe the design of the analysis is somehow wrong for Anduril.
The problem here is, that since it is a record, at the time of running, we don't actually know what are the file names. We do know that for instance, in CSVJoin, the output port name is csv, which means the file name will be csv.something, but that something is defined by the datatypes, and is not available for the user during the execution. The problem is more obvious in the case of generic output ports, where the downstream components define the file type. When iterating over records, the files are not even written to the disk yet.
But, we know that in arrays, the file names are known, since it's a product of a component in the form of an index file. Also, we know that all the files have been written on the disk at the time of creating the array. So, why not turn the record in to an array first:
inArray = std.makeArray(inRecord)
myRecord={}
for rec: std.iterArray(inArray) {
foo=SomeComponent(input=inRecord[rec.key], @name="some_"+rec.key)
myRecord[rec.key]=foo.output1
std.echo(rec.file)
}
Here we are using the record as an input for the component, while iterating over the array - doesn't really make a difference which one you use, the indexes are the same anyway.
The std.echo will now print the string to the file name in the corresponding port.