Nordico
Nordico

Reputation: 1307

How to access private variables in fortran modules?

I know the idea of private variables is that they shouldn't be accessed, and I do want it to work this way when using the module in the rest of the program, but I need it for the purpose of checking the internal workings of the module.

Say I have the following simplified example:

module mod
  implicit none
  private
  integer :: value
  public :: set_value

contains

subroutine set_value(input)
  implicit none
  integer,intent(in) :: input
  value=input
end subroutine

end module

And I now want to test the subroutine to see if it is actually doing what I want: I would like to write a program that uses the module, calls the routine set_value with input 8 and then checks if the internal variable value is now 8.

Can I do this? Or is it there another way to unit test initializers of private variables?

Upvotes: 2

Views: 3162

Answers (1)

casey
casey

Reputation: 6915

You have three approaches as I see them.

  1. write a get function to get the value and test. You indicate in the comments that this is sub-optimal though, so..

  2. If you have a compiler with Fortran 2003 support (e.g. any recent version of a modern Fortran compiler), declare the variable with the protected attribute instead of the private attribute. This will allow your variable to be read from any code, but not modified. This will enforce that it can only be set via your setter function but you can inspect its value directly in your unit test.

    integer, protected :: value
    
  3. Lastly, if all else fails, you can conditionally compile the module so that sometimes the variable is not private. For example, do this:

    module mod
      implicit none
      private
      integer :: value
      public :: set_value
    
    #ifdef UNITTESTING
      public :: value
    #endif
    
    contains
    ...
    end module
    

    Then change the filename from .f90 to .F90 so that it will be pre-processed (at least on gfortran and ifort). When you compile it normally, value will be private, but if you instead compile with the flag -DUNITTESTING then value will be public. When you compile your test cases, you use that flag and they can now inspect the variable directly.

Upvotes: 6

Related Questions