web-dev-qa-db-ja.com

「false」であるブール関数の引数に付けるコメントを修正しますか?

いくつかのオープンソースプロジェクトから、私は次のコーディングスタイルを集めました

void someFunction(bool forget);

void ourFunction() {
  someFunction(false /* forget */);
}    

ここでfalseが何を意味するのか、いつも疑問に思っています。それは「忘れる」という意味ですか、それとも「忘れる」は対応するパラメーターを参照していますか(上記の場合のように)、「false」はそれを否定することを意味していますか?

あいまいさを回避するために最も頻繁に使用されるスタイルと、最良の方法(またはいくつかのより良い方法)は何ですか?

素人の言葉で:

  • falseはリテラルです。
  • リテラルfalseを渡している
  • あなたはsomeFunctionに忘れないように言っている
  • あなたはsomeFunctionに、パラメータ忘れがfalseであることを伝えています
  • あなたはsomeFunctionに覚えているように言っています

私の意見では、関数が次のようになっているとよいでしょう。

void someFunction(bool remember);

あなたはそれを呼ぶことができます

void ourFunction() {
  someFunction(true);
} 

または古い名前を維持しながら、ラッパー関数を

void ourFunctionWithRemember() {
  someFunction(false);
} 

編集:

@Voracが述べたように、常に肯定的な単語を使用するように努めます。二重否定は混乱を招きます。

27

パラメータには適切な名前を付けることができます。関数の名前がわからないとわかりにくいです。コメントは関数の元の作者が書いたものだと思います。これは、falsesomeFunctionに渡すことの意味を思い出させるものでしたが、後で来る人にとっては、一見。

正の変数名Code Complete で推奨)を使用することが、このスニペットを読みやすくする最も簡単な変更です。

void someFunction(boolean remember);

次に、ourFunctionは次のようになります。

void ourFunction() {
    someFunction(true /* remember */);
}

ただし、列挙型を使用すると、いくつかのサポートコードを犠牲にして、関数呼び出しがさらに理解しやすくなります。

public enum RememberFoo {
    REMEMBER,
    FORGET
}

...

void someFunction(RememberFoo remember);

...

void ourFunction() {
    someFunction(RememberFoo.REMEMBER);
}

何らかの理由でsomeFunctionのシグネチャを変更できない場合、一時変数を使用すると、コードも読みやすくなります。これは、人間が解析しやすいコード。

void someFunction(boolean remember);

...

void ourFunction() {
    boolean remember = false;
    someFunction(remember);
}
14
Mike Partridge

変数の名前を変更して、ブール値が意味を持つようにします。

名前が曖昧であるため、関数の引数を説明するコメントを追加するよりも100万倍優れています。

10
enderland

よりわかりやすい名前のローカルブール値を作成し、それに値を割り当てます。そうすれば、意味がより明確になります。

void ourFunction() {
    bool takeAction = false;  /* false means to forget */
    someFunction( takeAction );
}    

変数の名前を変更できない場合は、コメントをもう少しわかりやすくする必要があります。

void ourFunction() {
    /* false means that the method should forget what was requested */
    someFunction( false );
}    
5
user53019

Qt-Style APIについて言及しているこの正確な状況について述べた優れた記事があります。そこでは The Boolean Parameter Trap と呼ばれ、読む価値があります。

その要点は次のとおりです。

  1. Boolが不要になるように関数をオーバーロードする方が良い
  2. Esailijaが示唆するように、列挙型を使用するのが最善です
3
Steven Evers

これは奇妙なコメントです。

コンパイラーから見ると、someFunction(false /* forget */);は実際にはsomeFunction(false);です(コメントは削除されています)。したがって、その行で行うことは、最初の(そして唯一の)引数をsomeFunctionに設定してfalseを呼び出すことです。

/* forget */はパラメータの名前です。それはおそらく、迅速な(そして汚い)リマインダーに過ぎないでしょう。あいまいさの少ないパラメータ名を使用するだけで、コメントはまったく必要ありません。

2
user2590712

クリーンコード のアドバイスの1つは、不要なコメントの数を最小限に抑えることです。1 (腐敗する傾向があるため)、関数とメソッドに適切に名前を付ける。

その後、コメントを削除します。結局のところ、Eclipseのような最近のIDEは、関数の上にマウスを置くと、ボックスにコードが表示されます。コードを見ると、あいまいさが解消されます。


1 いくつかの複雑なコードにコメントを付けても問題ありません。

1
BЈовић

明白な行動をとるために、コメントは嘘をつくことができます。したがって、誰かが(おそらくあなたが)truefalseに変更してコメントを更新しないため、説明をコメントに頼らずにコードを自己文書化する方が常に優れています。

APIを変更できない場合は、2つのオプションを使用します

  • コードに関係なく、常にtrueになるようにコメントを変更します。これを1回だけ呼び出す場合は、ドキュメントをローカルに保つため、これは良い解決策です。
 someFunction(false/* true =忘れる、false =覚える* /); `
  • 特に複数回呼び出す場合は、#definesを使用してください。
 #define FORGET true 
 #define REMEMBER false 
 someFunction(REMEMBER); 
1
Mark Lakata

私は コメントを常に真にすることについての答え が好きですが、このコードの基本的な問題を見逃していると思いますが、リテラルで呼び出されています。

メソッドを呼び出すときにリテラルを使用しないでください。ローカル変数、オプションのパラメーター、名前付きパラメーター、列挙型-それらを回避する最善の方法は、言語と利用可能なものに依存しますが、回避しようとします。リテラルには値がありますが、意味がありません。

1
jmoreno