私のラボにはたくさんのMATLABコードがあります。問題は、それを整理する方法が本当にないことです。すべての関数を呼び出すには同じフォルダーにある必要があるため(または、MATLABのpath
環境変数に多数のフォルダーを追加する必要があるため)、同じファイルに大量のファイルが存在することが運命にあるようです。フォルダ、すべてグローバル名前空間にあります。ファイルと関数を整理するより良い方法はありますか?なんらかのモジュールシステムがあればいいのに….
MATLABには、入れ子にしてクラスと関数の両方を含めることができるパッケージの概念があります。
+
のように、パスのどこかに+mypkg
を最初の文字として持つディレクトリを作成するだけです。次に、そのディレクトリにクラスまたは関数がある場合、mypkg.mything
と呼ばれることがあります。 import mypkg.mysubpkg.*
を使用してパッケージからインポートすることもできます。
一連の関数をパッケージに移動する際の主な問題の1つは、関数とクラスが、それらが存在するパッケージを自動的にインポートしないことです。これは、相互に呼び出すさまざまなmファイルに多数の関数がある場合、import
sをドロップするか、関数呼び出しを修飾するのにしばらく時間がかかる可能性があることを意味します。同様に呼び出されるサブ関数にインポートを配置することを忘れないでください。より詳しい情報:
http://www.mathworks.com/help/matlab/matlab_oop/scoping-classes-with-packages.html
Matlabの検索パスにフォルダーを追加する必要があるという問題はありません。私はstartup.m
を変更して、Matlabスタートアップディレクトリ内のディレクトリを再帰的に探し、それらをパスに追加します(すべてでsvn update
も実行されます)。このように、ディレクトリ構造を変更しても、Matlabは次に起動したときにすべての機能を引き続き表示します。
それ以外の場合は、@ objectNameフォルダーにすべてのメソッドを格納するオブジェクト指向のコードを調べることができます。ただし、これにより、パスを更新することで回避できる多くのコードの書き換えが発生する可能性があります(File
メニューからフォルダーをパスに追加すると、ボタンadd with subfolders
も表示されます)少しコードを移動します。
[〜#〜]編集[〜#〜]
一部の関数がそれらを直接呼び出す関数からのみ見えるようにコードを編成したい場合(およびOOPで再書き込みしたくない場合)、呼び出し関数をディレクトリに配置します。ディレクトリでは、private
というサブディレクトリを作成します。そこにある関数は、親ディレクトリの関数にのみ表示されます。これは、コードのサブセットに対していくつかの組み込みMatlab関数をオーバーロードする必要がある場合に非常に役立ちます。
コードを整理して再利用する別の方法は、MATLABのオブジェクト指向機能を使用することです。通常、各オブジェクトは「@」で始まるフォルダ内にあり、そのクラスのファイルが内部にあります。 (ただし、新しい構文では、単一のファイルで定義されたクラスに対してこれを必要としません。)クラスフォルダー内のプライベートフォルダーの使用により、MATLABはプライベートクラスメンバーもサポートします。 Matlabの 新しいクラス表記 は比較的完全に機能していますが、 古い構文 でも便利です。
ところで、私のstartup.m
これは、SVNチェックアウトを行う既知の場所を調べ、すべてのサブフォルダーを自動的にパスに追加します。
パッケージシステムはおそらく最高です。クラスシステム(@ClassNameフォルダー)を使用していますが、実際にはオブジェクトを作成しています。それを行わない場合、静的メソッドの束を書くだけではばかげています。役立つ可能性があることの1つは、すべてのMATLABコードをMATLABパス上にないフォルダーに配置することです。次に、必要なコードだけを選択的にパスに追加できます。
たとえば、「c:\ matlabcode\foo」と「c」\ matlabcode\barに保存されている2つのプロジェクトがあり、どちらも「c:\ matlabcode\common」に保存されている共通コードを使用している場合、関数「setupPaths .m "は次のようになります。
function setupPaths(projectName)
basedir = fullfile('c:', 'matlabcode');
addpath(genpath(fullfile(basedir, projectName)));
switch (projectName)
case {'foo', 'bar'}
addpath(genpath(fullfile(basedir, 'common')));
end
もちろん、これを拡張することもできます。明らかな拡張は、そのディレクトリの関数を使用するためにパスに追加する必要がある他のディレクトリを示すテキストファイルを各ディレクトリに含めることです。
コードを共有する場合のもう1つの便利な点は、「ユーザー固有の/ LabMember」ディレクトリ構造を設定することです。この場合、さまざまなラボメンバーが作業中のコードを保存します。そうすれば、必要に応じてそのコードにアクセスできますが、自分のコードと同じ名前の関数を作成するときに、そのコードを壊されることはありません。