Perl类::无法写入输出

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/

我不熟悉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/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)