2015-09-29 68 views
1

我知道私有變量的概念是不應該被訪問,我確實希望它在這個程序的其餘部分使用模塊時以這種方式工作,但我需要它來檢查內部工作的目的的模塊。如何訪問fortran模塊中的私有變量?

說我有以下簡單的例子:

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 

,我現在要測試的子程序,看是否確實是這樣做我想要什麼:我想編寫使用該模塊的程序,使用輸入8調用例程set_value,然後檢查內部變量value現在是8.

我可以這樣做嗎?還是有另一種方法來單元測試私有變量的初始值設定項嗎?

+4

寫一個'get_value'函數並用它來測試。 – casey

+0

即使我只會使用該功能進行測試?另外,我不會一次測試兩個例程嗎? – Nordico

+0

如果您不想關注@casey,只需將其設置爲公開以進行測試,然後將其設置爲私有! – innoSPG

回答

5

當我看到它們時,您有三種方法。

  1. 寫一個get函數來獲取值和測試。您在評論中指出這是次優,但如此..

  2. 如果您有支持Fortran 2003的編譯器(例如現代Fortran編譯器的任何最新版本),請使用protected屬性聲明該變量的private屬性。這將允許你的變量從任何代碼中讀取,但不能修改。這將強制它只能通過你的setter函數來設置,但你可以直接在你的單元測試中檢查它的值。

    integer, protected :: value 
    
  3. 最後,如果一切都失敗了,你可以有條件地編譯模塊,這樣有時變量不是私有的。例如,這樣做:

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

    然後從.f90文件名變更爲.F90,這樣它會被預處理(至少在gfortran和ifort)。當你正常編譯它時,value將是私有的,但是如果你用標記-DUNITTESTING編譯,那麼value將公開。當你編譯你的測試用例時,你使用該標誌,他們現在可以直接檢查變量。

+0

請不要條件編譯...替代可能會受到保護,請參閱http://stackoverflow.com/questions/15020460/protected-global-variables-in-fortran –

+1

@IanBush謝謝,我忘記了這一點。我已經添加了,但是保留了條件編譯部分作爲他們使用古代編譯器的機會的後備。 – casey

+0

非常好!但我不會刪除評論,因爲條件編譯是EVIL !!!!!! (坐下來,等待評論)(但我真的認爲這是全局變量的更糟糕形式) –