2009-08-06 13 views
32

変数、関数、サブルーチンののを含むFortran 90モジュールがあるとします。あなたが従わない大会あなたのUSE声明では、:どのようにFortran 90モジュールのデータを使用する

  1. 明示的なUSE [module_name], only : variable1, variable2, ...として、, only :の構文で使用しているどの変数/関数/サブルーチンを宣言?
  2. ブランケットを挿入USE [module_name]

一方で、only節はコードをもう少し冗長にします。しかし、コード内で自分自身を繰り返す必要があります。モジュールに変数/関数/サブルーチンのロットが含まれていると、扱いにくいものになります。

ここでは例です:

module constants 
    implicit none 
    real, parameter :: PI=3.14 
    real, parameter :: E=2.71828183 
    integer, parameter :: answer=42 
    real, parameter :: earthRadiusMeters=6.38e6 
end module constants 

program test 
! Option #1: blanket "use constants" 
! use constants 
! Option #2: Specify EACH variable you wish to use. 
    use constants, only : PI,E,answer,earthRadiusMeters 
    implicit none 

    write(6,*) "Hello world. Here are some constants:" 
    write(6,*) PI, & 
     E, & 
     answer, & 
     earthRadiusInMeters 
end program test 

更新 うまくいけば、誰かが "ちょうどC#でそれを再コーディングFortranの?!" のようなものを言います私はあなたに投票することができます。


更新

私は、FortranのUSE modulename Pythonのfrom modulename import *とを比較しTim Whitcomb's answerを、好き。前のスタックオーバーフローにされているトピック:

  • ‘import module’ or ‘from module import’

    • In an answer、マークロディは言及:

      は、 'モジュールのインポート*から' を使用しないでください。 合理的な大規模なコードの場合、 をインポートすると、 モジュールに接合する可能性があります。 を取り外すことはできません。その非常に 難しい 東あなたはもう インポートを使用していないと思うポイント に到達するためにそれを作る、「モジュール」から来ているかの項目コードに を使用し決定すること 困難であるが、これは、念のため。

  • ​​

    • dbr's answer

      が* Xのインポートから行いません含まれています - あなたは簡単に場所を見ることができない として、それは、理解することは非常に難しい あなたのコードを作りますメソッド はfrom(x import *; from y import *; my_func() - はmy_func 0123です。が定義されていますか?)

だから、私は明示的に

USE modulename, only : var1, var2, ... 

そしてStefano Borini mentions

などを経て、私はモジュール内で使用しているすべての項目を明記のコンセンサスに傾いています

あなたが大きいモジュールを持っている場合は、 が追加されたように感じるのは、 モジュールが大きすぎます。それを分割する。

+3

Fortranの問題の1つは、モジュールからインポートするときに、Javascriptのようにグローバル名前空間内のすべてを常にスローするということです。 Pythonでは、foo.bar import *からだけでなく、foo import barからも行うことができます。 fortranでは、あなたは選択肢がありません。 USEを使うたびに、あなたはimport *をやっていて、すべてをグローバルな名前空間に含めます。これは最悪のFortran 9Xの問題の1つです。 –

+0

@StefanoBorini:最後の文は、最近のFortranのバージョンで問題が解決されたことを意味しますか? – naught101

+0

@ naught101 nope –

答えて

15

これはバランスの問題です。

モジュールからいくつかのものだけを使用する場合は、使用しているものを明確に指定するために追加するだけです。

モジュールからたくさんのものを使用する場合は、指定するだけで多くのものが続くため、あまり意味がありません。あなたは基本的にあなたが使っているものをチェリーピッキングしていますが、本当の事実はあなたがそのモジュール全体に依存しているということです。

しかし、最終的に最良の考え方はこれです。ネームスペースの汚染が懸念されていて、大きすぎるモジュールがあり、あなただけが追加しなければならないと感じたら、モジュールが大きすぎるということです。それを分割する。

更新:Fortran? )

+5

これは、「モジュールがどれくらいの大きさであるべきか」に役立つヒューリスティックです。 –

3

USEの主な利点は、私が必要としないものでグローバルな名前空間を汚染しないようにすることです。

23

私はちょうどuse modulenameを実行していましたが、私のアプリケーションが成長してから、ソースコードをgrepに変えずに見つけるのがますます難しくなりました。他のコードのいくつかオフィスの周りに浮かんでも、ファイルごとに1つのサブルーチンが使用されますが、それは独自の問題がありますが、テキストエディタを使用してコード内を移動し、必要なものを素早く追跡できます。

これを経験した後、可能な限りuse ... onlyを使用して変換されました。また、Pythonを起動して、from modulename import *と同じ方法で表示しています。モジュールがあなたに与えるすばらしいことがたくさんありますが、グローバルな名前空間を厳重に管理することをお勧めします。

+0

私はPythonモジュールをインポートすることにあなたの類推が好きです - 良い考え方! – Pete

+1

正確に。私は明示的なインポート "use ... only"を使うだけです。Pythonのように、 "from ... import"を使うだけです。私はこれが正しいアプローチだと思う。 –

5

ここでの質問に正確に答えていないのは、何らかの理由で、あなたのモジュールを分割して名前空間の衝突を開始したくない場合は、私が有用であると思った別の解決策を投げてください。派生型を使用すると、複数の名前空間を1つのモジュールに格納できます。

変数が論理的にグループ化されている場合は、グループごとに独自の派生型を作成し、この型のインスタンスをモジュールに格納して、必要に応じてグループをインポートすることができます。

小さな例:いくつかはユーザー入力であり、その他はさまざまな初期化の結果である多数のデータがあります。

module basicdata 
    implicit none 
    ! First the data types... 
    type input_data 
     integer :: a, b 
    end type input_data 
    type init_data 
     integer :: b, c 
    end type init_data 

    ! ... then declare the data 
    type(input_data) :: input 
    type(init_data) :: init 
end module basicdata 

は今、サブルーチンのみinitからのデータを使用している場合、あなたはちょうどそれをインポートします。

subroutine doesstuff 
    use basicdata, only : init 
    ... 
    q = init%b 
end subroutine doesstuff 

これは間違いなく普遍的に適用可能なソリューションではありません、あなたは、派生型の構文からいくつかの余分な冗長性を取得し、あなたのモジュールがbasicdataのソートではなく、その代わりにallthestuffivebeenmeaningtosortoutのバラエティの場合はもちろん、ほとんど役に立たないでしょう。とにかく、私はこのように脳にフィットするコードを得ることにいくつかの幸運をもたらしました。

0

私は少し遅れて相手にだけど、あなたは定数のみのセットと、必ずしも計算値後にしている場合、あなたはCのように行うと、インクルードファイル作成することができます。内部で

をファイル、 例えば、constants.for

real, parameter :: pi = 3.14 
real, parameter :: g = 6.67384e-11 
... 


program main 
    use module1, only : func1, subroutine1, func2 
    implicit none 

    include 'constants.for' 
    ... 
end program main 

削除するように編集 "本当の(4)" いくつかは、それは悪い習慣だと思うよう。

+0

元の質問にそれが必要でないときに 'real(4)'を使うという悪い習慣を人々に教えてください。また、インクルードのアプローチがより良い、あるいはより簡単であるということに私は同意できません。 –

+0

リアル(4)はコピー/ペーストで、私の最後には癖があります。 私はあなたの他のコメントについて考えましたが、とにかくそれを残しました。人々が同じことを達成できる無数の方法があります。人々が実験して好きなものを見つけることが重要です。私の意見では、 "include"ファイルは、Makefileを使用せず、 "-I"を追加しないと難しくなります。 – Forrest

1

これまでのほとんどの回答と一致して、use ..., only: ...は、意味のあるときにタイプを使用し、可能な限りpython thinkingを適用する方法です。もう1つの方法は、インポートされたモジュールで適切な命名規則をprivate/public文とともに使用することです。

たとえば、netcdfライブラリはnf90_<some name>を使用します。これにより、インポート側の名前空間汚染が制限されます。

use netcdf ! imported names are prefixed with "nf90_" 

nf90_open(...) 
nf90_create(...) 
nf90_get_var(...) 
nf90_close(...) 

同様に、このライブラリへncioラッパーは(... nc_readnc_writenc_<some name>を使用しています。

ことで簡単に見読者のために十分であるように重要なのは、use: ..., only: ...はあまり関係行われるような設計で、あなたはより良い、ヘッダにprivate/public適切な属性を設定することにより、インポートされたモジュールの名前空間を制御したいです彼らが直面している「汚染」のレベルを評価する。これは基本的にはuse ..., only: ...と同じですが、インポートされたモジュール側にあります。したがって、各インポート時ではなく、1回だけ書き込まれます)。

もう1つ:オブジェクト指向とPythonに関する限り、私の見解の違いは、部分的には、それが比較的新しい標準であるという理由から、fortranは実際にタイプバインドされた手続きを奨励しないということです。いくつかのツールがありますが、合理的でないことはほんの珍しいことです)、手続きのない派生型コピー(type(mytype) :: t1, t2t2 = t1)などの便利な動作が破られるためです。つまり、タイプだけでなく、タイプバインドされたすべてのプロシージャーをインポートする必要があることがよくあります。これだけでは、FortranコードをPythonに比べてより冗長にすることができ、プレフィックス命名規則のような実用的な解決策が役立つかもしれません。

IMO、結論は次のとおりです:Pythonが教えているように、これを読む人のためのコーディングスタイルを選択してください。最も良いのは、それぞれのインポートでより冗長なuse ..., only: ...ですが、場合によっては、(あなたが十分訓練されていれば)簡単な命名規則がそれを行います。

1

はい、use module, only: ...を使用してください。複数のプログラマーがいる大規模なコードベースの場合、コードを誰にも従うのが簡単になります(または単にgrepを使用します)。

includeを使用しないでください。その代わりに、小さいモジュールを使用してください。 Includeは、使用モジュールと同じレベルでコンパイラによってチェックされないソースコードのテキスト挿入です(FORTRAN: Difference between INCLUDE and modulesを参照)。 Includeは、人間とコンピュータの両方がコードを使用することを一般的に困難にします。つまり、コードを使用しないでください。 Ex。 from mpi-forum: "mpif.hインクルードファイルの使用は強く推奨されず、将来のバージョンのMPIでは廃止される可能性があります。" (http://mpi-forum.org/docs/mpi-3.1/mpi31-report/node411.htm)。

+0

2番目の段落に最初の文のような文を追加しないでください。あなたの答えは、スタンドアロンの回答として適しているか、そうではないし、投稿しない。コメントを投稿するには、最初に担当者を取得し、それは簡単です。そのような文章では、あなたの質問が削除されるよう投票する人々だけを招待します。そのような回答/コメントを削除する特別な理由があります。 –

+0

@VladimirFこれは良いアイデアと削除の正当な理由です。私はこれを偶然見つけて、私が投稿することを決めたことを忘れてしまうと仮定すると、インクルードの使用が非難されるべきであり、少なくとも積極的に落胆するような悪い習慣であると思うからです。それは一般に、人間とコンピュータの両方にとってより困難にし、それから使用すべきではありません。 mpi-forumからのEx:「mpif.hインクルードファイルの使用は強く推奨されておらず、MPIの将来のバージョンで廃止される可能性があります。」 (https://www.mpi-forum.org/docs/mpi-3.1/mpi31-report/node411.htm)。だから私は有効な答えを出し、発言を加えた。編集された投稿。 –

+0

私は同意します。この引用符を答えに入れることができます。残念ながら、OpenMPIマニュアルでは、少なくともバージョン1.8では、サブルーチンのマニュアル入力の前に 'include mpif.h 'しか表示されません。 –

関連する問題