-2

私はPerlの初心者です。私はいくつかのスクリプトを書いていますmyprint()が、いくつかのフラグ(verbose / debugフラグ)に基づいて渡されたものを出力するという独自のprintを定義したいと思います。

open(FD, "> /tmp/abc.txt") or die "Cannot create abc.txt file";
print FD "---Production Data---\n";
myprint "Hello - This is only a comment - debug data";

myprint()誰かが関数 のサンプルコードを手伝ってくれませんか?

4

2 に答える 2

5

独自のロギングシステムを作成することに関心がありますか、それとも、オフにできる(そして、オフにしたときにパフォーマンスの低下がほとんど発生しない)プログラムの適切な部分にロギングステートメントを配置する方法を知りたいですか?

使い始めるのが簡単で、段階的に検出して使用できる機能の世界も提供するロギングシステムが必要な場合は、Log::Log4perlが適しています。イージーモードがあり、目的のログレベルを指定でき、目的のレベルを超えるログメッセージのみを出力します。

#!/usr/bin/env perl

use strict; use warnings;

use File::Temp qw(tempfile);
use Log::Log4perl qw(:easy);

Log::Log4perl->easy_init({level => $INFO});

my ($fh, $filename) = tempfile;

print $fh "---Production Data---\n";

WARN 'Wrote something somewhere somehow';

このスニペットは、 File::Tempを使用して一時ファイルを開くためのより良い方法も示しています。

ビルトインプリントをオーバーライドすることに関しては…非常に特殊な状況を除いて、ビルトインをいじるのは本当に良い考えではありません。組み込み関数のオーバーライドperldoc perlsubに関するセクションがあります。この質問に対する受け入れられた答えは、オーバーライドできないPerlビルトインをリストしています。それらの1つです。print

しかし、実際には、ロギングシステムを作成するために組み込みをオーバーライドする必要はありません。

したがって、すでに作成されているロギングシステムで処理できない場合は、「フラグの値に応じて条件付きで出力する関数を作成するにはどうすればよいですか」と質問しているようです。

これが1つの方法です:

#!/usr/bin/env perl

package My::Logger;
{
    use strict; use warnings;
    use Sub::Exporter -setup => {
        exports => [
            DEBUG => sub {
                return sub {} unless $ENV{MYDEBUG};
                return sub { print 'DEBUG: ' => @_ };
            },
        ]
    };
}

package main;

use strict; use warnings;

# You'd replace this with use My::Logger qw(DEBUG) if you put My::Logger
# in My/Logger.pm somewhere in your @INC
BEGIN {
    My::Logger->import('DEBUG');
}

sub nicefunc {
    print "Hello World!\n";
    DEBUG("Isn't this a nice function?\n");
    return;
}

nicefunc();

使用例:

$ ./yy.pl
「こんにちは世界」
$ MYDEBUG = 1 ./yy.pl
「こんにちは世界」
DEBUG:これは素晴らしい機能ではありませんか?
于 2012-04-07T02:26:28.703 に答える
2

Sinanが私が推奨する答えをすでに持っているので、私はこれに答えるつもりはありませんでしたが、今夜私はまた、次の中間Perlの「ファイルハンドル参照」の章に取り組んでいました。それは私があなたの質問にそれらを適応させることなく直接コピーするいくつかの関連する段落です:


IO::NullおよびIO::Interactive

出力をどこにも送信したくない場合もありますが、どこかに送信する必要があります。その場合、IO :: Nullを使用して、与えたものをすべて破棄するファイルハンドルを作成できます。見た目も動作もファイルハンドルと同じですが、何もしません。

use IO::Null;

my $null_fh = IO::Null->new;

some_printing_thing( $null_fh, @args );

また、出力が必要な場合もありますが、そうでない場合もあります。ログインしてターミナルでプログラムを実行している場合は、多くの出力を確認したいと思うでしょう。ただし、 cronを使用してジョブをスケジュールする場合、ジョブを実行する限り、出力についてはあまり気にしないでしょう。IO :: Interactiveモジュールは、違いを伝えるのに十分スマートです。

use IO::Interactive;

print { is_interactive } 'Bamboo car frame';

サブルーチンはis_interactiveファイルハンドルを返します。サブルーチンの呼び出しは単純なスカラー変数ではないため、中括弧で囲んで、Perlにファイルハンドルであることを通知します。

「何もしない」ファイルハンドルについて理解したので、誰もが書きがちな醜いコードを置き換えることができます。出力が必要な場合とそうでない場合があります。そのため、多くの人は、条件付きの事後式を使用して、ステートメントをオフにする場合があります。

print STDOUT "Hey, the radio's not working!" if $Debug;

$debug_fhその代わりに、必要な条件に基づいて異なる値を割り当てif $Debug 、すべての最後に醜いものを省くことができますprint

use IO::Null;

my $debug_fh = $Debug ? *STDOUT : IO::Null->new;

$debug_fh->print( "Hey, the radio's not working!" );

IO :: Nullの背後にある魔法は、「未開封のファイルハンドルGLOBでのprint()」について、間接的なオブジェクト表記(たとえば print $debug_fh)で警告を発する場合がありますが、正常に機能します。直接フォームではその警告は表示されません。

于 2012-04-07T06:49:56.333 に答える