【问题标题】:is it allowed to pass pipes to constructors?是否允许将管道传递给构造函数?
【发布时间】:2020-01-16 14:44:43
【问题描述】:

我试图在 Perl 中做一些非常奇特的事情,但我认为我正在承受后果。实际上,我不知道我试图做的事情是否可行。

我的主程序创建一个这样的管道:

pipe(my $pipe_reader, my $pipe_writer);

(最初是 pipe(PIPE_READER, PIPE_WRITER) 但我在尝试调试时更改为常规变量)

然后它分叉,但我认为这在这里可能无关紧要。孩子这样做:

my $response = Response->new($pipe_writer);

Response 的构造函数很简单:

sub new {
    my $class = shift;
    my $writer = shift;

    my $self = {
        writer => $writer
    };
    bless($self, $class);
    return($self);
 }

然后孩子会写下它的回应:

$response->respond(123, "Here is my response");

响应代码如下:

sub respond {
    my $self = shift;
    my $number = shift;
    my $text = shift;
    print $self->{writer} "$number\n";
    print $self->{writer} "$text\n";
    close $self->{writer}
}

这会触发一个奇怪的编译错误:'String found where operator expected ... Missing operator before "$number\n"?'在第一次打印时。当然,这是打印的正常语法,除了我有对象属性而不是普通句柄,而且它恰好是管道,而不是文件句柄。所以现在我想知道我是否不允许这样做。

【问题讨论】:

    标签: perl


    【解决方案1】:

    来自print

    如果您将句柄存储在数组或散列中,或者通常每当您使用比裸字句柄或普通的无下标标量变量更复杂的表达式来检索它时,您将必须使用一个块返回文件句柄值,而不是,...

    print { $files[$i] } "stuff\n";
    print { $OK ? *STDOUT : *STDERR } "stuff\n";
    

    (我的重点)

    所以你需要

    print { $self->{writer} } "$number\n";
    

    或者,根据Borodin 的评论

    $self->{writer}->print("$number\n");
    

    print 的语法比较特殊,例如this postthis post。一方面,print 之后必须有一个“简单”文件句柄或 一个块评估为 1,如上所述,以满足解析器。

    但是对于dereference (arrow) operator,文件句柄被发现是一个IO::File 对象,因此在其上调用其父级的IO::Handle::print 方法。 在 v5.14 之前,必须有 use IO::Handle; 才能工作,但现在不是了。请参阅this post 和其中的链接了解更多信息。

    注意print FILEHANDLE LIST 不是indirect method call, 即使看起来是这样。它只是在相当特殊的语法规则下对 print 内置函数的函数调用。只有明确的-> IO::Handle 方法被调用。


    它要么在遇到方法调用(并失败)时被祝福到类中,要么在创建时;我无法在文档中找到它或以其他方式解决文件句柄是在创建时还是按需提供的

    perl -MScalar::Util=blessed -wE'
        pipe(RD,WR);                   
        say *WR{IO};                   #--> IO::File=IO(0xe8cb58)
        say blessed(WR)//"undef";      #--> undef
    '
    

    (警告未使用的RD)我们不能对词法文件句柄执行此操作,因为它们不在符号表中。

    但曾经需要一个文件句柄 IO::FileIO::Handle 对象(取决于 Perl 版本)。

    【讨论】:

    • $self->{writer}->print("$number\n")
    • @Borodin 谢谢。绝对需要提及——更新。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-31
    • 2014-03-07
    • 2011-09-24
    • 2012-01-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多