Perl:用于登录特定文件的库
我正在为我的资料创建一个库,以便在其中记录特定文件上的错误。不幸的是,如果我只启动库的一个实例,它就可以工作,但如果我启动多个实例,它就不能工作 这种情况下的结果是,输出全部记录在最后一个文件中,而不是像我预期的一半 这是main.plPerl:用于登录特定文件的库,perl,Perl,我正在为我的资料创建一个库,以便在其中记录特定文件上的错误。不幸的是,如果我只启动库的一个实例,它就可以工作,但如果我启动多个实例,它就不能工作 这种情况下的结果是,输出全部记录在最后一个文件中,而不是像我预期的一半 这是main.pl eval 'exec /usr/bin/perl -I `pwd` -S $0 ${1+"$@"}' if 0; use strict; use MyLibrary; my ($rc, $test_2, $test_1); # The output is
eval 'exec /usr/bin/perl -I `pwd` -S $0 ${1+"$@"}'
if 0;
use strict;
use MyLibrary;
my ($rc, $test_2, $test_1);
# The output is not going into this file
exit $test_1 if (($test_1 = MyLibrary->new("/tmp", "test_1")) !~ "HASH");
# It is going all into this file
exit $test_2 if (($test_2 = MyLibrary->new("/tmp", "test_2")) !~ "HASH");
exit $rc if ( $rc = $test_1->test() );
exit $rc if ( $rc = $test_2->test() );
这是MyLibrary.pm
package MyLibrary;
use strict;
use Symbol;
use vars qw($VERSION @ISA @EXPORT %default);
@EXPORT = qw(
);
$VERSION = '1.00';
require 5.000;
%default;
my $fh;
sub new
{
my $rc;
my ($proto, $log_dir, $log_file) = @_;
my $class = ref($proto) || $proto;
my $self = { %default };
bless($self, $class);
$fh = gensym;
($self->{'log_dir'}, $self->{'log_file'}) = ($log_dir, $log_file);
return $rc if ( $rc = $self->open_log_file() );
return $self;
}
sub destroy
{
my $rc;
my $self = shift;
return $rc if ( $rc = $self->close_log_file() );
}
sub open_log_file
{
my $self = shift;
open $fh, ">>$self->{'log_dir'}/$self->{'log_file'}" or die "cannot open file $self->{'log_dir'}/$self->{'log_file'}";
return 0;
}
sub close_log_file
{
my $self = shift;
close($fh) or die "cannot close $self->{'log_dir'}/$self->{'log_file'}";
return 0;
}
sub test
{
my $self = shift;
print $fh "[$self->{'log_file'}]\n";
return 0;
}
1;
还有一件事。。。在本例中,我使用$fh
作为全局变量,同时我希望将此变量作为%default
哈希的一部分。但是,如果我尝试将所有$fh
发生的事件替换为$self->{'fh'}
,则会出现以下错误:
String found where operator expected at MyLibrary.pm line 75, near "} "[$self->{'log_file'}]\n""
(Missing operator before "[$self->{'log_file'}]\n"?)
syntax error at MyLibrary.pm line 75, near "} "[$self->{'log_file'}]\n""
在这种情况下,第75行将如下所示:
sub test
{
my $self = shift;
Row 75 =>>> print $self->{'fh'} "[$self->{'log_file'}]\n";
return 0;
}
而相应审查的完整库为:
package MyLibrary;
use strict;
use Symbol;
use vars qw($VERSION @ISA @EXPORT %default);
@EXPORT = qw(
);
$VERSION = '1.00';
require 5.000;
%default;
sub new
{
my $rc;
my ($proto, $log_dir, $log_file) = @_;
my $class = ref($proto) || $proto;
my $self = { %default };
bless($self, $class);
$self->{'fh'} = gensym;
($self->{'log_dir'}, $self->{'log_file'}) = ($log_dir, $log_file);
return $rc if ( $rc = $self->open_log_file() );
return $self;
}
sub destroy
{
my $rc;
my $self = shift;
return $rc if ( $rc = $self->close_log_file() );
}
sub open_log_file
{
my $self = shift;
open $self->{'fh'}, ">>$self->{'log_dir'}/$self->{'log_file'}" or die "cannot open file $self->{'log_dir'}/$self->{'log_file'}";
return 0;
}
sub close_log_file
{
my $self = shift;
close($self->{'fh'}) or die "cannot close $self->{'log_dir'}/$self->{'log_file'}";
return 0;
}
sub test
{
my $self = shift;
print $self->{'fh'} "[$self->{'log_file'}]\n";
return 0;
}
1;
根据经验,似乎
print
语句中的文件句柄不能是任意表达式。这实际上只是对代码的一个小修改,但为了编译MyLibrary.pm
,我替换了:
print $self->{'fh'} "[$self->{'log_file'}]\n";
与:
还有其他一些小的调整,但这段代码对我很有用:
MyLibrary.pm
我不相信使用5.000代码>非常适合你。找到仍在运行的Perl4.x的机会非常渺茫。现在,任何早于Perl5.8的东西都早已过时(或者,如果不是的话,它应该是)
上面没有显示的代码中有许多小的改进
testcase.pl
第n次样本运行
看起来我在添加print\u data
函数之前运行了一次以前版本的testcase.pl
,在添加print\u data
函数之后运行了四次
$ perl -I$PWD testcase.pl
OK 1
OK 2
OK 3
OK 4
OK 5
Finished
$ cat /tmp/test_1
[test_1]
[test_1]
Extra information
[test_1]
Extra information
[test_1]
Extra information
[test_1]
Extra information
$ cat /tmp/test_2
[test_2]
[test_2]
Missing syncopation
[test_2]
Missing syncopation
[test_2]
Missing syncopation
[test_2]
Missing syncopation
$
欢迎来到堆栈溢出。请尽快阅读这一页。你是否考虑过使用它的众多相关模块?如果是这样,你为什么不使用它?如果没有,请这样做。不幸的是,我不能使用外部库满足客户的需求,这就是为什么我需要了解如何自己制作。嗯;运气不好,不得不不断地重新发明轮子。请尽量确保它们是圆的。我感到有点惊讶的是,在Perl本身的相同条款下获得许可的软件存在明显的问题。如果您可以使用Perl,为什么不使用其他软件呢?然而,律师并不擅长将逻辑应用于此类情况。
package MyLibrary;
use warnings;
use strict;
use vars qw($VERSION @ISA @EXPORT %default);
@EXPORT = qw();
$VERSION = '1.00';
require 5.000;
sub new
{
my ($proto, $log_dir, $log_file) = @_;
my $class = ref($proto) || $proto;
my $self = { %default };
bless($self, $class);
$self->{'log_dir'} = $log_dir;
$self->{'log_file'} = $log_file;
$self->open_log_file();
return $self;
}
sub destroy
{
my $rc;
my $self = shift;
return $rc if ( $rc = $self->close_log_file() );
}
sub open_log_file
{
my $self = shift;
my $log_file = "$self->{log_dir}/$self->{log_file}";
open $self->{'fh'}, ">>", $log_file or die "cannot open file $log_file";
return;
}
sub close_log_file
{
my $self = shift;
close($self->{'fh'}) or die "cannot close $self->{'log_dir'}/$self->{'log_file'}";
return;
}
sub print_data
{
my $self = shift;
my $fh = $self->{fh};
print $fh @_, "\n";
}
sub test
{
my $self = shift;
my $fh = $self->{'fh'};
print $fh "[$self->{'log_file'}]\n";
return 0;
}
1;
#!/usr/bin/env perl
use warnings;
use strict;
use MyLibrary;
my ($rc, $test_2, $test_1);
my $counter = 0;
sub counter
{
printf"OK %d\n", ++$counter;
}
counter;
# The output is not going into this file
exit $test_1 if (($test_1 = MyLibrary->new("/tmp", "test_1")) !~ "HASH");
counter;
# It is going all into this file
exit $test_2 if (($test_2 = MyLibrary->new("/tmp", "test_2")) !~ "HASH");
counter;
exit $rc if ( $rc = $test_1->test() );
counter;
exit $rc if ( $rc = $test_2->test() );
counter;
$test_1->print_data("Extra information");
$test_2->print_data("Missing syncopation");
print "Finished\n";
$ perl -I$PWD testcase.pl
OK 1
OK 2
OK 3
OK 4
OK 5
Finished
$ cat /tmp/test_1
[test_1]
[test_1]
Extra information
[test_1]
Extra information
[test_1]
Extra information
[test_1]
Extra information
$ cat /tmp/test_2
[test_2]
[test_2]
Missing syncopation
[test_2]
Missing syncopation
[test_2]
Missing syncopation
[test_2]
Missing syncopation
$