Perl类::无法写入输出
我不熟悉perl中的面向对象编程。所以,我有一个愚蠢的问题 什么-- 我正在写一个脚本,它将做一些事情并将结果写入流(STDOUT或网络) 怎么-- [main.pl]Perl类::无法写入输出,perl,class,object,printing,Perl,Class,Object,Printing,我不熟悉perl中的面向对象编程。所以,我有一个愚蠢的问题 什么-- 我正在写一个脚本,它将做一些事情并将结果写入流(STDOUT或网络) 怎么-- [main.pl] #!/usr/bin/perl use strict; require const::StreamTypes; require output; my $out = output->new("output"); $out->writeLine("Sample output"); [输出.pm] #!/usr/
#!/usr/bin/perl
use strict;
require const::StreamTypes;
require output;
my $out = output->new("output");
$out->writeLine("Sample output");
[输出.pm]
#!/usr/bin/perl
use strict;
require const::StreamTypes;
package output;
my $OUTSTR;
sub new{
my $class = shift();
my $stream = shift();
if($stream eq const::StreamTypes->STDNET){
}elsif($stream eq const::StreamTypes->STDWEB){
}else{
*OUTSTR = *STDOUT;
}
my $self = {
"_outStream" => $stream,
"_outStreamPtr" => $OUTSTR
};
bless($self, $class);
}
sub writeLine{
my $msg = shift();
print(OUTSTR "$msg\n");
}
return 1;
那么,有人能帮我理解这里出了什么问题吗?”cas程序运行时没有错误,但没有输出
谢谢
$outtr
和*outtr
是非常不同的事情——在您担心面向对象编程之前,您应该澄清您对此的误解
也就是说,您可能可以通过让所有内容都引用$outsr
来修复此脚本:
...
}else{
$OUTSTR = *STDOUT;
}
...
print $OUTSTR "$msg\n";
直接将文件句柄传递给对象的构造函数怎么样
package output;
sub new {
my ($class, $fh) = @_;
bless { file_handle => $fh }, $class;
}
sub writeLine {
my $self = shift;
my $line = shift;
print {$self->{file_handle}} $line;
}
1;
用法示例:
my $output = output->new(\*STDOUT); # write to stdout
my $socket = IO::Socket::INET->new('www.perl.org', PeerPort => 'http(80)', Proto => 'tcp');
my $output = output->new($socket); # write to a socket
我在这里改变了几件事:
我不建议使用package全局变量(my$outsr;),因为多个实例需要不同的流,这会造成混乱 我肯定养成了对所有属性使用访问器的习惯。您可以使用一个轻量级的系统,比如,或者您甚至有幸使用我们的。当然,还有一些其他模块也以不同的方式提供访问器
包输出;
严格使用;
使用警告;
使用自动模具;
使用Class::Accessor“moose-like”;
具有“超流”=>(is=>“rw”);
次新{
我的($class$stream)=@;
我的$self=祝福({},$class);
如果(0){
# ...
}否则{
打开(my$outStream,'>&',\*STDOUT);
$self->outStream($outStream);
}
返回$self;
}
子写入线{
我的($self,$msg)=@;
打印{$self->outStream}“$msg\n”;
}
返回1;
Moose将为您创建一个构造函数,但您可以按如下方式轻松插入参数处理:
使用驼鹿
has "outStream" => ( is => 'rw' );
sub BUILDARGS {
my ( $class, $stream ) = @_;
open( my $outStream, '>&', \*STDOUT );
return {
outStream => $outStream,
};
}
请不要对文件句柄使用裸名称。使用词汇文件句柄 以下几行假设某个地方有一个哈希
%type\u handlers
,如下所示:
{ const::StreamTypes->STDNET => \&constructor_for_stdnet_handles
, const::StreamTypes->STDWEB => \&constructor_for_stdweb_handles
}
然后,您可以将构造函数的底部替换为:
my $handler = $type_handlers{ $stream };
my $outstr
= $handler ? $handler->()
: do { my $h; open( $h, '>&', \*::STDOUT ) and $h; }
;
return bless( {
_outStream => $stream
, _outStreamPtr => $outstr
}
, $class
);
然后,writeLine
变成:
sub writeLine {
my ( $self, $msg ) = @_;
( $self->{_outStreamPtr} || *::STDOUT{IO} )->say( $msg );
}
- 这种方法在有人祝福自己进入你的类的情况下更为健壮
my $q_and_d = bless {}, 'output';
Carp::croak( 'No outstream!' )
unless my $h = Params::Util::_HANDLE( $self->{_outStreamPtr} )
;
不清楚你想要达到什么目的?我可以在运行程序时去掉对const::StreamTypes的所有引用,并将对象打印出来:
output=HASH(0x7fbfcb004038)
。您可能希望writeLn有一个my($self,$msg)=@代码>行而不是shift
?我希望输出模块处理低级细节。但是你的建议看起来很有趣…谢谢你的回复。我当然会研究它,但当我按照您的建议更改代码时,它得到了以下输出--output=HASH(0x100834c20)