7

ツール フローを実行するスクリプトがたくさんあります。Makefile と同様ですが、Perl で行います。

これらのフローの一部として、Perl スクリプトは環境変数を設定しますが、それがいつ発生するかを知るのは必ずしも容易ではないため、フローの個々の段階を再現するのが難しい場合があります。

環境が変化したときにコールバックを登録できるように %ENV にフックする方法はありますか?

結ぶだけでいいの?%ENV は既に引き分けのように動作しています。

フォローアップ: はい。あなたはそれに結びつくだけです。

4

5 に答える 5

9

ああ。私はただお尻を鳴らしました。とにかく、tie を介して既存の変数への変更を監視できるようにする監視パッケージが存在すると思われます。これは興味深い問題のように思えたので、The Blue Camel の「tie」ドキュメントを掘り下げ始めたとき、既存の変数に何が起こるかについての定義はありませんでした (つまり、参照はどこかに保存されていますか?)。だから、「perl tie "existing variable"」をググった。残念ながら、私が見つけたリンクは社会的に受け入れられないもの (海賊版) でした。

しかし、幸運を祈ります。

とにかく、明確にするために、「高度なPerlプログラミング」の第9章、「Tie」の章にあります。評判の良いサイトからコピーを購入してください:-)

于 2009-03-26T01:50:17.917 に答える
4

これは実行可能です。以下を実行するとおそらくパフォーマンスが低下すると思います。考えられるすべてのケースをカバーしていないことは確かですが、これで間違いなく始めることができます。

use strict;
use warnings;

tie %ENV, 'change_noticer', %ENV or die $!;

$ENV{PATH} .= ":test";
print $ENV{PATH}, "\n";
delete $ENV{PATH};

package change_noticer;

use strict;
use warnings;
use Carp;
use Tie::Hash;
use base 'Tie::StdHash';

sub DELETE {
    my $this = shift;

    carp "deleting \$ENV{$_[0]}";
    $this->SUPER::DELETE(@_);
}

sub STORE {
    my $this = shift;

    carp "altering \$ENV{$_[0]}";
    $this->SUPER::STORE(@_);
}

sub TIEHASH {
    my $class = shift;
    my $this  = bless {}, $class;

    while( my ($k,$v) = splice @_, 0, 2 ) {
        $this->{$k} = $v;
    }

    return $this;
}
于 2009-03-26T14:00:40.843 に答える
1

行間を読んで、別のことを試してみてください。タスクを実行するために「system(...)」を呼び出す代わりに、外部タスクを呼び出す前に環境を出力する「my_system(...)」を実装します。コマンドラインから「env ...」コマンドを使用して、タスクの1つを再作成できます

# show the environment in which an external command runs:
sub my_system
    {
    print map { $_ . "='" . $ENV{ $_ } . "'\n" } keys( %ENV);
    print "'" . join( "' '", @_) . "'\n";
    return system( @_);
    }
于 2009-03-27T18:33:25.017 に答える
1

私が考えることができる唯一のことは、フックできる%ENVIRONMENTインターフェイスとして機能する、という名前の関連付けられた変数を作成することです。次に、代わりに%ENV常に使用することを確認してください。%ENVIRONMENT%ENV

于 2009-03-26T00:00:15.417 に答える