この記事は,
Datatool社のRichard Johnson氏が書いた
"MATLAB Programming Style Guideline"
を自分なりに翻訳したものです.
この文書は
MATLABのコードをより素晴らしいものにするための
多数のコーディング作法について書かれています.
翻訳結果は以下の各リンクから読むことができます.
0. MATLAB Programming Style Guidelines : About This Document - MY ENIGMA
1. MATLAB Programming Style Guidelines : Introduction - MY ENIGMA
2. MATLAB Programming Style Guidelines : Naming Conventions - MY ENIGMA
3. MATLAB Programming Style Guidelines : Constants and Structures - MY ENIGMA
4. MATLAB Programming Style Guidelines : Functions - MY ENIGMA
5. MATLAB Programming Style Guidelines : General - MY ENIGMA
6. MATLAB Programming Style Guidelines : Files and Organization - MY ENIGMA
7. MATLAB Programming Style Guidelines : Statements - MY ENIGMA
8. MATLAB Programming Style Guidelines : Layout, Comments and Documentation - MY ENIGMA
もし,これらの文章に意見や質問,誤謬などがあれば,
それぞれの記事にコメントしてもらえると幸いです.
また,今回の一連の文章は
リンクフリーです.
また,出典を明確にして頂ければ,
内容の転載も可能です.
その際は,コメント欄を利用して一言お願いします.
この"MATLAB Programming Style Guideline"の英語の原本は
以下のリンクからダウンロードできます.
・MATLAB Programming Style Guidelines - File Exchange - MATLAB Central
また,Richard Johnson氏は,
より詳細なMATLAB Programming Style Guidelineを広めるために,
以下の本を出版しています.
もし,より深くMATLABのプログラミング作法を学びたい方は,
こちらも参考にすると良いと思います.
最後に,
今回の翻訳は,Richard Johnson氏に直接許可を頂いています.
Richard Johnson氏の寛大な心と素晴らしい仕事に,
深く感謝します.
Statements
変数と定数
ルール1:メモリの問題が無い限り,変数の再利用はしない.
すべての変数はユニークで,
その部分だけで使用されることを約束すれば,
コードの可読性は向上します.
その変数の定義を誤解するような変数の使い方は控えるべきです.
ルール2: 関連のある同型の変数は,同一のコードで一緒に宣言する.
同様に,関連の無い変数は,
同一のコードで一緒に宣言すべきではありません.
これによって,変数のグループを理解しやすくなります.
persistent x, y, z global REVENUE_JANUARY, REVENUE_FEBRUARY
ルール3: 重要な変数はファイルの初めにコメントとして説明する
他の言語において,
その変数が宣言された時に,
その変数の説明をすることは一般的です.
しかし,MATLABでは変数の宣言は基本的にしないので,
コメントとして,その変数の説明を書きます.
ex)
% pointArray Points are in rows with coordinates in columns.
ルール4: 定数の説明は,定数の定義の後ろにコメントとして書く.
このルールによって,
この定数の値の決定理由や,
使用方法,制限条件などを記述することができます.
ex)
THRESHOLD = 10; % Maximum noise level found by experiment.
グローバル変数
ルール1:グローバル変数の使用は最小限にしましょう.
関数の可読性とメンテナンス性のために,
関数に値を渡す時は,
グローバル変数ではなく,引数で渡すようにしましょう.
グローバル変数を使わなくてはいけない状況において,
その内の幾つかは "persistent"*1や, "getappdata"*2コマンドで
使用しなくてもよくなることが多い.
ルール2:グローバル定数は最小限にしましょう.
グローバル定数は使用せずに,
mファイルやmatファイルを使用して,
変数を宣言しましょう.
これによって,
どこで定数が定義されるのかが明確になります.
同様に,意図しない再定義も防ぐことができます.
もし,そのファイルにアクセスされることを望まないなら,
グローバル定数の構造体を利用することを考えましょう.
ループ
ルール1:ループ変数はループの直前で初期化する.
これによってループの速度が向上し,
もしループがすべてのインデックスの分だけ
回っていなかった時に
変な値になることをを防ぐことができます.
result = zeros(nEntries,1); for index = 1:nEntries result(index) = foo(index); end
ルール2:breakやcontinueはループの中で使用するのは最低限にしましょう.
このルールは,goto文に関するものと同じです.
breakやcontinue文はコードがそれによって
より可読性を向上させるものでない限り,
使用しないほうがいいでしょう.
ルール3: ネストしたループの最後にはコメントを入れましょう.
ネストした長いループの最後にコメントを入れることは,
コードの可読性を向上させますし,
そこまでのコードでどのような行為が行われたのかを
伝えることができます.
条件文
ルール1:複雑な条件文を使用することは控えるべきです.
もし,複雑な条件文を使用しなければならない時には,
以下の例のように,一時的な論理変数を利用すべきでしょう.
論理変数を利用することにより,
プログラム自体が自身のドキュメントになります.
そして,よりコードを読みやすくし,
デバックしやすくするでしょう.
if (value>=lowerLimit)&(value<=upperLimit)&~ismember(value,valueArray) : end
以上のプログラムは,以下のように書き直すべきです.
isValid = (value >= lowerLimit) & (value <= upperLimit); isNew = ~ismember(value, valueArray); if (isValid & isNew) : end
ルール2:基本的にif文を使う時には例外処理としてelse文も一緒に使用する.
このルールによって,
コードの可読性が向上し,
そのif文の例外の部分がどのようになるかを
わかりやすくします.
fid = fopen(fileName); if (fid~=-1) : else : end
ルール3:条件文で"if 0"は使用すべきではありません.
"if 0"を使うことによって,
その部分をコメントのように
利用しないようにすることができます.
しかしこれは,
コードが実際にどのような振る舞いをするのかを
不明瞭にするので,使用しないほうがいいでしょう.
ブロックコメントにしたいのなら,
エディタの機能を使って,ブロックコメント化するべきです.
ルール4:switch文にはotherwise文を必ず付けましょう.
switch文で,otherwise文を付け忘れるのは,
よくあるミスです.
これは,コードが不可解な振る舞いをする
可能性があるので,止めましょう.
switch (condition) case ABC statements; case DEF statements; otherwise statements; end
ルール5: switch文の条件変数はstring文にしましょう.
文字列変数は,それ自体が意味を持つので,
数字の変数を使用するよりも,
コードの意図を伝えやすくなります.
一般的なこと
ルール1:曖昧なコードを書くのは止めましょう.
これはプログラマは陥りがちなことですが,
このシェイクスピアの言葉に感化される人は非常に多いです.
"短いことこそ,ジョークの真髄だ."
MATLABを書く時にも使えると考えるのも
しょうがないことなのかもしれません.
簡潔なコードを書くことは,
様々な言語の特徴を知る上で,
有効な方法だと言えるでしょう.
しかし,一般的に,
コードの最終的なゴールは,
言語の特徴を学ぶことではなく,
コードの明確性を向上させることです.
Math WorksのSteve Lordはこのように言っています.
"今から,一ヶ月後,
自分がそのコードを見たら,
何をするコードなのかを理解することができるか?
それを常に心に止めておくことが重要なのです.”
他にも,コードの簡潔性のみを追い求めることの問題を
多くの人が指摘しています.
Martin Fowlerは言いました.
"どんな馬鹿でも
コンピュータが理解できるコードは書くことができる.
けど,良いプログラマというのは,
人間が理解できるコードを書くことができるんだ"
KreitzbergとShneidermanもこう言っています.
"プログラミングは楽しいものです.
そして,わかりにくくすることもできます.
しかし,それらは決して両立しません."
ルール2:括弧を使いましょう.
MATLABには,演算子の優先権に関するルールが文書化されています.
しかし,だれがそのようなルールの詳細まで覚えているでしょう.
もし,誰もがわかりやすいコードを書くのであれば,
それぞれの式をわかりやすくするために括弧を利用すべきです.
これによって,論理式を拡張したい場合に,
非常にコードが読みやすくなります.
ルール3:数式の中では,数字をそのまま使用するのは最小限にしましょう.
数式の中で数字を使いたい時には,
代わりに名前のついた定数に数字を代入して,
その定数を数式に利用するようにしましょう.
なぜなら,もし数字が明確な意味を持たなかったなら,
そのコードの可読性は著しく損なわれるでしょう.
代わりに名前のついた定数を利用することにより,
可読性は著しく向上します.
また,このルールを徹底することにより,
その数字の値を変更したい時に,
ファイル内のその数字の値をすべて変更するよりも,
たった一つの定数宣言の値のみを変更すればよいので,
よりコードの改変が楽になります.
ルール4 浮動小数点数の定数は,必ず少数点の前の数字も書きましょう.
これは数学の構文のルールとして決められているものです.
また,0.5という数字は.5と表記するより,
読みやすいのは確かです.
これでは整数の5と見間違えてもしょうがないといえます.
ex)
◯ THRESHOLD = 0.5; × THRESHOLD = .5;
ルール5 浮動小数点数の比較は細心の注意を払う.
二値の表現は問題を引き起こしがちです.
次の例を見てみましょう.
shortSide = 3; longSide = 5; otherSide = 4; longSide^2 == (shortSide^2 + otherSide^2) ans = 1
これは想像通りです.
では次はどうでしょうか?
scaleFactor = 0.01; (scaleFactor*longSide)^2 == ((scaleFactor*shortSide)^2 +(scaleFactor*otherSide)^2) ans = 0
なぜこうなるのでしょうか?