Perlのデフォルトのスコープ動作がそのようになっているのはなぜですか?

Dec 10 2020

私は学校でPerlを学んでおり、現在、myキーワードの使用とPerlでのスコープについて学んでいます。(参考までに、Perlで「my」キーワードをどのように使用すればよいかを調べていました。)この質問が他の場所でまだ行われていないことを願っていますが、そうでない場合は...なぜPerlのデフォルトの動作がそのままであるのですか?

Cスタイルのデフォルトのスコープが最も理にかなっているように思えます...ブロック内で変数を宣言すると、その変数はそのブロック内に存在し、そのブロックを離れると、その変数にアクセスできなくなります。Perlでこの動作を指定するには、myキーワードを使用する必要があるのはなぜですか?変数のスコープをそれが使用される場所だけに制限することは良い標準的な振る舞いであるmyように思われ、常に使用することは非常に冗長であり、コードの乱雑さに寄与するようです。

周りの誰かが興味を持った場合に備えて、食料品店に足を運び、すぐにそのようなものの好みのブランドを大声で宣言してから買い物を続けるようです(おそらくそうではありませんでした)。

(重複の可能性があるため、この質問は削除される可能性があります...ファイルスコープで「my」を使用してPerl変数を宣言するのはなぜですか?)

回答

9 ikegami Dec 10 2020 at 06:30

字句スコープの変数が必要な場合は、何らかの形式の宣言が必要です。[1]


Cスタイルのデフォルトスコープが最も理にかなっているように思えます...ブロック内で変数を宣言すると、その変数はそのブロック内に存在し、そのブロックを離れると、その変数にアクセスできなくなります

それがPerlでの動作とまったく同じです。int iCでを使用して変数を宣言する場合my $i、Perlでを使用します。どちらも、字句スコープの変数を作成します。つまり、現在のブロックと含まれているブロックにのみ表示される変数です。ブロック外でコードを実行する場合、変数にアクセスできません。Perlの変数のスコープは、Cの変数のスコープと同じです。[2]

// Can't use `i` here.           # Can't use `$i` here.
{                                {
   // Can't use `i` here.           # Can't use `$i` here. int i = 4; my $i = 4;
   printf("%d\n", i);       4       say $i; { { printf("%d\n", i); 4 say $i;
      int i = 5;                       my $i = 5; printf("%d\n", i); 5 say $i;
   }                                }
   printf("%d\n", i);       4       say $i; } } // Can't use `i` here. # Can't use `$i` here.

  1. Pythonには明示的な変数宣言はありませんが、字句スコープの変数もありません。Python変数は関数スコープです。

  2. ただし、変数の有効期間は同じではありません。スカラーは、Perlに存在するブロックの終わりを超えて存続させることができますが、Cの同様の変数(「自動保存期間」を持つ変数)には当てはまりません。

    例えば、

    # You can't use `@a` outside of the sub,
    # But you can use the created array anonymously.
    sub f { my @a = qw( abc def ); return \@a; }
    

    その意味で、my $xは動的に割り当てられた構造体に似ています。

6 Schwern Dec 10 2020 at 07:00

それがラリーウォールが1987年にそれをした方法であり、Perl5はその決定との下位互換性を維持しているからです。字句変数は1994年のPerl5まで導入されず、それまでにPerl4プログラムのインストールベースはかなり大きくなりました。

理由を推測します。Perlはアプリケーション言語として考えられていなかったので、1つになりました。Perl 1は、sed、awk、およびBourneシェルのより強力な代替手段として1987年に作成されました。

通常はsed、awk、shを使用する問題があるが、それらの機能を超えているか、少し速く実行する必要があり、Cで愚かなことを書きたくない場合は、perlが適している可能性があります。

Perl1.0マニュアルから。

sedおよびawkプログラムは通常1行です。そしてシェルでは変数はグローバルです。Perl 1の目的を考えると、それは問題ありませんでした。

受け入れられているソフトウェアエンジニアリング標準は、過去数十年で大きく変化しました。システムが小さくて単純だった頃は、グローバル変数がより受け入れられていました。複雑さが増すにつれて、グローバル変数はますます危険になります。

1 lordadmira Dec 12 2020 at 11:15

厳密に言えば、Perlの変数のデフォルトのスコープはパッケージグローバルです。宣言する必要のない変数。それはあなたにPerlの哲学について多くを教えてくれます。これはタスク指向であり、迅速なプロトタイピングと迅速で汚いプログラミングに優れています。コマンドラインで完全なプログラムを記述して、かなり複雑なタスクを実行できます(perl -e)。マゾヒストだけがやるでしょうperl -e 'use strict; ...'。変数を書くだけで、それらは機能します。それらの哲学の1つはDWIMです-私が言いたいことをしてください。これは、何かを行う前に世界を定義する必要があるほとんどの「ハード」プログラミング言語とは正反対です。

その後、我々が得たラリーの良い時間でstrictuse varsmyour、およびstate変数の管理を完了します。それらは私たちのために機能しますが、その逆ではありません。実際、特定のデータをグローバルに配置しないことは失礼なプログラミングと見なすことができます。私は必ずしも次の人よりよく知っているわけではなく、彼が私のコードやモジュールを内省したり変更したりしたいのであれば、それは問題なく隣人です。

これは、Perlの作成者であるLarryWallによる講演への非常に有益なリンクです。

Perl、最初のポストモダンコンピュータ言語

Perlの文化

しかし、真剣に、Perlカルチャーに重要なアイデアの芽があるとすれば、それはこれです。コントロールが多すぎることは、コントロールが少なすぎることと同じくらい致命的です。制御が必要であり、混乱が必要です。

プログラミングは難しいです、スクリプトを始めましょう...

Unixシェルプログラミングの欲求不満は、Perlの作成に直接つながりました。シェルスクリプティングは、その動詞のほとんどがその制御下になく、名詞が貧弱で、文字列とファイルに制限されており、誰が何を知っているのかという事実によって本質的に制限されていることがわかりました。私は愚かなコンピューター言語と話したくありません。入力した文字列をコンピューター言語で理解できるようにしたい。

詳細については、perl.comをご覧ください。