8

$Module::varNameモジュールがゲッター/セッターメソッドを提供しなかった場合に直接アクセスして、モジュールのグローバル変数を取得すること、またはさらに重要なことに設定することに関して、Perlのベストプラクティスは何であるか疑問に思いました。

それが私に悪臭を放つ理由は、それがカプセル化を回避するという事実です。私がPerlでそれを行うことができるという理由だけで、私は私がすべきかどうか完全に確信していません(モジュールにゲッター/セッターを追加するなどの代替手段が実際にあると仮定します)。

4

3 に答える 3

9

変数がパブリックAPIの一部である場合、カプセル化に違反していません。(そうでない場合は別の問題です。)

動的スコープを利用できるため、直接アクセスが望ましいと思います。

local $Module::varName = 42;

これにより、他のコードとの競合が発生するModule可能性が低くなります。

于 2010-05-27T16:28:05.280 に答える
2

グローバルモジュール変数は過去に流行していましたが、現代のPerlのインターフェイスとして「悪い形式」と見なされていました。Perlは現在22〜23歳であり、スタイルと慣習が変わったことを認識することが重要です。:)パッケージ変数に付随する非常に優れた機能がいくつかあるため、それでも適切な場合があることに注意してください。いつものように、良い解決策が何であるかを見ることは経験と実践の問題です。

パッケージ変数の最適な使用法を理解するには、実際にどのように機能するかを理解する必要がありますlocallocalのperldocヘルプを確認してください。$My::VariableLocalを使用すると、パッケージ内の(例として)のようなパッケージ変数を取得し、その動的スコープバージョンをMy作成できます。通常、その場で変更すると、プログラム全体に影響を及ぼし、持続します。小さなプログラムの場合、それは大したことではないかもしれません。大きなものの場合、これは悲惨な副作用をもたらす可能性があります。 その変数に一時的な変更を加えることができます。これは現在のスコープに限定されます。$My::Variablelocal

仕組みは次のとおりです。

use 5.012;
use warnings;

package My;

our $Variable = 5;

package main;

say $My::Variable; # prints 5
$My::Variable = 7;
say $My::Variable; # prints 7
{  # create a new lexical scope
    local $My::Variable = 10; # create a new dynamic scope for $My::Variable
                              # that will persist to the end of the lexical scope
    say $My::Variable;  # prints 10
}
say $My::Variable;  # end of the lexical scope for the localized
                    # $My::Variable, so prints 7 again

事実上、パッケージ変数を安全な方法で使用できます。残念ながら、誰もがローカルについて知っているわけではないので、グローバル変数を壊してしまうことがよくあります。良い使い方(例)を文書化することはlocal常に役に立ちます。

適切なオブジェクトカプセル化を備えたゲッター/セッターは、これの多くを防ぎますが、常にではありません。ローカル変数と同じように機能させるには、多くの追加作業を行う必要があります。パッケージ変数をローカライズできることの最も良い点は、たとえばデバッグ変数に対して、一時的な変更を非常に簡単に実行できることです。通常、次のようなパターンを実行する必要があります。

{
    my $current_variable  My::get_variable();
    $My::set_variable($new_value);

    # Do code work

    $My::set_variable($current_variable);
}

ローカルの場合、これは次のようになります。

{
    local $My::Variable = $new_value;

    # do code work
}

(ちなみに、同じ理由で、字句変数に対してもこれを実行できるといいのですが...できません。)したがって、いくつかの点で、パッケージ変数理にかなっています。それはあなたがそれをどのように使いたいかによります。のようなもの

  • 変数のデバッグ
  • 頻繁に変更されない/変更されるべきではないグローバル構成

ただし、定期的に変更する必要がある場合は

  • 定期的に使用される変数(の恐ろしいインターフェースを参照File::Find
  • 一時的な構成
  • 「オブジェクト」変数

基本的に、複数回またはまれな状況で変更する必要があるもの、あるいは生成されたオブジェクトにカプセル化する必要があるものはすべて、パッケージ変数を避けます。

于 2010-05-27T16:38:05.747 に答える
1

モジュールがアクセサーを提供しない場合は、アクセサーを作成して使用し、パッチを送信します。

于 2010-05-27T17:43:10.530 に答える