Fortran refactoring
- From: "phillip.news@xxxxxxxxx" <phillip.news@xxxxxxxxx>
- Date: 28 Jun 2006 14:24:09 -0700
I wanted to share a refactoring tip that's helped me tremendously.
It's been made possible by Fortran 90.
I work on several legacy Fortran applications, with routines frequently
over 1000 lines, where the routine includes both high-level logic and
low-level details. In order to separate these, I take the subroutine
in question, add a "contains" statement at the bottom, and break it
into contained subroutines. I don't (initially) move any of the
variables, but it allows the high-level logic of the code to show
through quickly without requiring major restructuring. If the
restructuring proves useful, I then go on to break these subroutines
out of the containing subroutine, which allows me to do this process
again if I need to.
Here's an example:
!*********** START OF EXAMPLE ************
subroutine x(a,b,c)
! declarations
! thousands of lines of code (perhaps with comments)
end subroutine x
!************ END OF EXAMPLE *************
After I get done, the code will look something like this:
!*********** START OF EXAMPLE ************
subroutine x(a,b,c)
! declarations
call initialize_x
do iteration = start, finish
call process_x
end do
call log_output_x
call cleanup_x
contains
subroutine initialize_x
! the initialization code (memory allocations,
! variable initializations, opening files etc)
! copied from the original routine
end subroutine initialize_x
subroutine process_x
! the processing code copied verbatim from the original
end subroutine process_x
subroutine log_output_x
! the output code copied from the original routine
end subroutine log_output_x
subroutine cleanup_x
! the cleanup code (deallocations,
! file closing, etc) from the original
end subroutine cleanup_x
end subroutine x
!************ END OF EXAMPLE *************
Obviously, this contrived example isn't the only way to break up the
code. And in fact, I often find myself breaking the codes I have into
20 or 30 routines, because the original code had so many unrelated
parts.
If you're working in the main program, it can also contain subroutines
and functions, so this technique works there as well.
One of the key benefits of contained subroutines is that they're scoped
so that they can see all of the variables available in the containing
program. If you keep all of the variable declarations at the
containing routine level, the variables are automatically shared
between all contained subroutines. So if you've picked a poor place to
split the code (i.e., logically, it should have happened a few lines to
either side of where you actually split it), the result will still
work. This is great for a quick-and-dirty refactoring to aid
understanding of legacy code.
The obvious next step would be to group related contained subroutines
together into a module, but that's more work than this is. This
technique can be done in a few minutes (perhaps an hour for a really
big file), keeps results identical, and improves the readability of the
code almost immediately.
I hope people find this tip useful.
Any other techniques people have found to be particulary useful for
refactoring?
Phillip
.
- Follow-Ups:
- Re: Fortran refactoring
- From: Bil Kleb
- Re: Fortran refactoring
- From: Richard Maine
- Re: Fortran refactoring
- Prev by Date: Efficient way to pass different shaped arrays?
- Next by Date: Re: heap allocation of arrays
- Previous by thread: Efficient way to pass different shaped arrays?
- Next by thread: Re: Fortran refactoring
- Index(es):
Relevant Pages
|