Search code examples
oopmodulefortranoverriding

Can a Fortran module override a subroutine in another module?


(BTW, this does not involve functions in derived types.)

I want to do something like the following. I have module test1:

cat test_mod_1.F90

module test1

        contains

                subroutine sub1()
                       ! do interesting stuff that any inheriting module
                       ! will want to do ....
                       ! then do something specific to this module:
                        call sub2()
                end subroutine sub1

                subroutine sub2()
                        print *, "I am test1"
                end subroutine sub2

end module test1

test1 is used by module test2:

> cat test_mod_2.F90
module test2


        use test1, test1_sub2 => sub2

        contains

                subroutine sub2()
                        print *,"I am test2"
                end subroutine sub2

end module test2

(By the way, without the "=>" line, test2 won't even compile.)

Then I have a main program that uses test2, not test1:

> cat testmain.F90
program testmain
        use test2
        call sub1()
end program

I want to get the message "I am test2," but things don't work out:

> gfortran -o tester test_mod_1.F90 test_mod_2.F90 testmain.F90
> ./tester
 I am test1

Is there any way to convince the main program to use test2's sub2() instead of test1's?


Solution

  • No.

    If you want customisable behaviour in sub1 that is best described by a user provided procedure, then pass a user provided procedure as an argument.

    module test1
      implicit none
    contains
      subroutine sub1(sub2_override)
        ! Declare sub2_override to be a optional dummy procedure that 
        ! has the same interface as the procedure known as sub2.  
        !
        ! Actual procedures associated with this dummy must having matching 
        ! characteristics.
        procedure(sub2), optional :: sub2_override
        
        !...
        if (present(sub2_override)) then
          call sub2_override
        else
          call sub2
        end if
      end subroutine sub1
      
      subroutine sub2
        print *, "I am test1"
      end subroutine sub2
    end module test1
    
    program testmain
      use test1
      implicit none
      call sub1
      call sub1(my_sub2)
    contains
      subroutine my_sub2
        print *, "I am my_sub2"
      end subroutine my_sub2
    end program testmain