admin管理员组文章数量:1124390
In OOP Fortran, we are using derived types to exchange data with external files via a namelist. I dislike that when you write a namelist to a file, the full inheritance tree is included in the variable name.
Consider this MWE:
program main
type :: parenttype
integer :: parentvar
end type
type,extends(parenttype) :: childtype
integer :: childvar
end type
type(childtype) :: ioobj
namelist /ionml/ ioobj
! Using "shallow" paths to member variables in the code.
ioobj%parentvar = -1
ioobj%childvar = -2
! Read "shallow" nml file (depth 2 for variables from all inheritance levels)
open(unit=1, file="in.nml", status="OLD")
read(unit=1, nml=ionml)
close(unit=1)
ioobj%parentvar = ioobj%parentvar + 1
ioobj%childvar = ioobj%childvar + 1
! Write "deep" nml file (name includes parents, depth will depend on inheritance level)
open(unit=2, file="out.nml", status="NEW")
write(unit=2, nml=ionml)
close(unit=2)
! Read "deep" nml file (works just as with the "shallow" file)
open(unit=3, file="out.nml", status="OLD")
read(unit=3, nml=ionml)
close(unit=3)
print*, "parent var:", ioobj%parentvar, " child var:", ioobj%childvar
end program
Now take the following namelist file in.nml
. Let's call its format “shallow”, since the variables inside ioobj
are all addressed without extra steps:
&ionml
ioobj%parentvar = 9
ioobj%childvar = 13
/
The program reads this file, and writes an out.nml
whose entries have a “deep” format:
&IONML
IOOBJ%PARENTTYPE%PARENTVAR=10 ,
IOOBJ%CHILDVAR=14 ,
/
(This is the output from gfortran 11.4.0; the result from ifort 2021.7.0 is the same up to whitespace.)
From the Fortran side of things, both namelist files are behaving equivalently (the namelist parser accepts both the “shallow” format ionml%parentvar
and the “deep” format ionml%parenttype%parentvar
), so far so good. I still would like to have control over this (i. e. decide against the “deep” variant, and in favor of the “shallow” variant), for various reasons:
- Inclusion of the inheritance hierarchy is redundant, since the origin of a member variable is known anyway.
- It is a cluttered interface. End users are distracted with information that they do not need to know. In post-processing, this encourages anti-patterns of including boilerplate and/or ugly workarounds (I've seen all of this).
- Increased size of input files, information dilution.
- Risk for breaking compatibility when internally refactoring the hierarchy (parsing will fail, even if great care has been taken to keep the “shallow” API intact)
- External tools (e. g. post-processing via f90nml) don't know that the two formats are equivalent. Additional overhead is necessary to use the input and output files interchangeably.
- It just feels wrong to address member variable with a different depth in the code vs. the namelist files. (Violation of the principle of least astonishment.) Fair enough, I could also use the “deep” variant
ioobj%parenttype%parentvar
directly in the Fortran code, but this not just doesn't solve the incoherence between the two formats, but IMHO also defeats the purpose of object orientation (separation of interface and implementation).
Can I modify the write
process for namelists, so that it produces the “shallow” format rather than the “deep” format?
I have not found any hint of doing so in the ifort documentation and the Oracle language reference. I would consider monkey-patching (sed -i 's/%[^ =]*%/%/'
) only as the very desperate last resort.
本文标签: fortranShallow vs deep namelist writeStack Overflow
版权声明:本文标题:fortran - Shallow vs. deep namelist write - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1736629027a1945736.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论