web-dev-qa-db-ja.com

PythonおよびPHP

問題は、PythonやPHPなどで変数宣言がない場合にどう対処するかです。

ほとんどの言語では、新しい変数を導入するか、既存の変数を参照するかをコンパイラーに知らせる方法があります。Perlのmyuse strict)または\newcommand\revewcommand LaTeXで。これは、エラーと頭痛の2つの主要な原因を防ぎます。

(1)(PHP)のように、2つの異なる目的で誤って同じ名前の変数を使用している

$v = $square * $height;
<...lots of code...>
foreach ($options as $k => $v)
    echo "For key $k the value is $v\n";
<...lots of code...>
echo "The volume is $v";

または多くの厄介な(PHP)

$a = [1, 2, 3];
foreach ($a as $k => &$v)
    $v++;
foreach ($a as $k => $v)
    echo "$k => $v\n";

(ここにバグがありますか?試してみてください););そして

(2)タイプミスを防ぐ(PHP):

$option = 1;
$numberofelements = 1;
if ($option)
{
    $numberofelenents = 2;
}
echo $numberofelements;

(ここにバグがありますか?PHPは静かに実行されます)。

my(Perl)のようなものを使用する

use strict; 
my $option = 1;
my $numberofelements = 1;
if ($option)
{
    $numberofelenents = 2;
}
say $numberofelements;

(Perlはすぐにバグを報告します)は小さな努力であり、デバッグ時間と(さらに重要なことに)誤ったプログラムによる損失(潜在的に非常に大きな)の両方で大きな利益をもたらします。

ただし、一部の言語、特にPython、PHP、JavaScriptは、これらのタイプのバグからの保護を提供していません。

私の質問は、これにどのように効果的に対処できるかです。

私が予測できる唯一の方法は、2つの関数(PHP)を作成することです。

function a ($x)
{
    if (isset ($x))
        die();
    else
        return &$x;
}

そして

function the ($x)
{
    if (isset ($x))
        return &$x;
    else
        die();
}

そして常にそれらを使用します:

a($numberofelements) = 1;
the($numberofelenents)++;
say the($numberofelements);

もちろん、これは非常に面倒です。そのようなエラーから効果的に保護するより良い方法はありますか?

いいえ、「別の言語を使用する」、「注意してエラーを発生させない」、「コードを小さな関数に分割する」は適切な回答ではありません(後者はタイプ1のエラーから保護するがタイプ2のエラーからは保護しない可能性があります)。

5

私の経験では、上記の問題を回避する方法は3つあります。

  1. 変数のスコープを制限する
  2. 変数に意味のある説明的な名前を付けます
  3. エラーを通知するためにプリコンパイラーを使用します(DovalはPythonのPylintについて言及しました)

1)変数のスコープを制限すると、最初のエラーが制限されます。同じ名前を含む可能性のある変数は少なくなります。オッズは衝突がないということです。変数は、使用されるスコープ内でのみ宣言することにより、スコープを制限できます。これが機能する理由は、コード内の自然なサイクルの結果として変数が破棄されるためです。明確にするために、以下に例を示します。

class:
    classVariable = "classVar";

    function ThisIsAFunction(functionVar) {
        var functionVar2 = "functionVar2";
        if functionVar > functionVar2 :
            var ifStatementVar = "ifStatementVar";

            for i in range(0,2):
                ifStatementVar += i;
            // i will go out of scope here
        // ifStatementVar will go out of scope here
    // functionVar and functionVar2 will go out of scope here

2)変数に意味のある名前を付けると、同じ変数名の再利用を防ぐのに役立ちます。変数に名前を付ける際のポイントは、変数を十分に具体化して、その名前を再利用できないようにすることです。コードをリファクタリングするとき、目的と意味をよりよく反映するように名前を変更できる関数、変数、クラスの名前を探すことをお勧めします。適切な変数名の例は次のとおりです。

function GetSumOfTwoIntegers(intFirstNum, intSecondNum):
    return intFirstNum + intSecondNum;

良い名前を決定するとき、多くの矛盾があります。誰もが独自のスタイルを持っています。確認すべき主なことは、メソッド、パラメーター、またはクラスが何をして使用することになっているのかを自分自身や他の人に明確にすることです。メソッド名としてのGetSumOfTwoIntegersは、このメソッドを呼び出すすべての人に、2つの整数を渡す必要があり、結果として合計を受け取ることを伝えます。

3)最後に、プリコンパイラを使用して、発生した誤りを通知できます。適切なIDEを使用している場合は、エラーが通知されます。 Visual Studioは、Intellisenceを使用して、コンパイルする前に開発者にエラーを通知します。ほとんどの言語には、この機能をサポートするIDEがあります。いずれかを使用すると、2番目の問題が確実に解決されます。

誰かが特定の方法で言語の構文を作成することを選択する理由は、特定するのが困難です。 Pythonの場合、作成者がコードを書くときにタイプを減らしたいと思った可能性が高いと私は考えます。 PythonでHello Worldプログラムを作成するには、printステートメントのみが必要です。 Javaで同等のプログラムを作成するには、さらに多くの入力が必要です。とにかく、作成者がこの構文を選択した理由は本当にわかりません。

2
Cameron McKay

分析ツールに加えて、あなたのIDEはこれらのタイプの問題を解決するのにも役立ちます。これらのタイプのことをEclipseよりもはるかに効果的に処理するため、私はPyCharmに移行しました&PyDev。これらの問題を防ぐのに役立つ、より視覚的なIDE=です。

2
Unknown Coder

ソリューションは3つしかありません。

  1. このために時々バグが発生することを受け入れ、発生したバグに対処してください
  2. リント/静的分析ツールを使用します(例 pylint
  3. 別の言語を使用する
0
Doval