Sage-Code Laboratory
index<--

Fortran Modules

Modern Fortran is a multi-paradigm programming language. It does not have support fo classes, but has similar concepts. It has support for abstraction, encapsulation, inheritance and polymorphism. To use these features you need to understend Fortran modules.

Module syntax

We have already talk about module syntax in the structure section. Remember a module can encapsulate declarations and subprograms. We can use modules to define and implement object oriented components.

Syntax pattern

module <name>
    !static (often exported) data definitions
    ...
contains
    !procedure definitions and interfaces
    ...
end module <name>

Notes: Best practice is to create one module in one file. Fortran enable one module to be split in many files. Also one single file can contain many modules.

Member Access

By default module members are public. You can use keywords, private and public to disable/enable explicit access to specific members. In next example we will create private and public members.

Object Oriented

In fortran 2003 you can create object oriented modules. Public members of modules can be accessed using symbol "%", that is usually "." in other languages.

example: circle.f95

module class_Circle
  implicit none
  real, private, parameter :: pi = 3.14159265d0
  type, public :: Circle
     real :: radius
   contains
     procedure :: area => circle_area
     procedure :: print => circle_print
  end type Circle
contains
  function circle_area(this) result(area)
    class(Circle), intent(in) :: this
    real :: area
    area = pi * this%radius**2
  end function circle_area

  subroutine circle_print(this)
    class(Circle), intent(in) :: this
    real :: area
    area = this%area()  
    print *, 'radius = ', this%radius, ' area = ', area
  end subroutine circle_print
end module class_Circle

A module do not work alone. You need to create a program that uses the module. In the main program you import the module by using "use" statement, then you can access its members:

main program
program circle_test
  use class_Circle
  implicit none

  ! Declare a Circle.
  type(Circle) :: test  
  real :: radius
  print *, "Enter 0, for exit."
  do
     write (*,"(a)", & 
     advance="no") "radius:"

     read *, radius
     if (radius == 0) exit
     test = Circle(radius)    
     
     ! Call bound subroutine
     call test%print          
end program 
console output
~/fortran-demo$ ./circle
Enter 0, for exit.
radius:1
radius=  1.00area=     3.142
radius:2
radius=  2.00area=    12.566
radius:10
radius= 10.00area=   314.159
radius:20
radius= 20.00area=  1256.637
radius:1.5
radius=  1.50area=     7.069
radius:0
~/fortran-demo$ 

Note: In this example we have used a special option for print: advance="no". This will enable user to enter the number immediatly after ":" and do not create a new line for print.


Read next: Error Handling