在Perl中,\*STDIN与STDIN相同吗?

qvsjd97n  于 2022-12-13  发布在  Perl
关注(0)|答案(2)|浏览(152)

我是Pythonizer的作者,我试图将www.example.com的代码CGI.pm从标准Perl库翻译成Python。

read(\*STDIN, $$buff, $len, $offset)

\*STDINSTDIN是同一个东西吗?我不明白他们为什么这样使用它。谢谢你的帮助!
该模块还引用了\*main::STDIN-这是否也与STDIN相同(我会在python中将普通的STDIN转换为sys.stdin)?代码:

foreach my $fh (
    \*main::STDOUT,
    \*main::STDIN,
    \*main::STDERR,
) { ... }
vltsax25

vltsax251#

与其逐行翻译CGI.pm,我建议您理解接口,然后做Python会做的任何事情。或者,更好的是,忘记它的存在。翻译通常看起来像是一个直接的替换,但是由于在新语言中使用的库和结构非常不同,因此您只会产生新的bug。既然你无论如何都要制造新的bug,你不妨做一些更聪明的事情。
但是,我对你的情况一无所知,所以让我们回到字面上的问题。
您看到的是:

# Read data from a file handle
sub read_from_client {
    my($self, $buff, $len, $offset) = @_;
    local $^W=0;                # prevent a warning
    return $MOD_PERL
        ? $self->r->read($$buff, $len, $offset)
        : read(\*STDIN, $$buff, $len, $offset);
}

不要担心Perl代码,只要在Python中做你需要做的事情来满足接口。给定一个缓冲区和一个长度,从文件句柄中获取更多的数据。由于你没有处理mod_perl(我猜,因为你会怎么做?),你可以忽略那里的大多数东西。
\*main::STDIN\*STDIN是对typeglob的引用,typeglob是一种跟踪所有同名Perl变量(标量、数组、哈希、子例程、文件句柄和其他一些变量)的方法。STDIN标识符是一个特例变量,默认为main,因此在前面添加包main::可能只是为了让开发人员感到舒适。
当你在一个需要处理文件句柄的地方使用这些引用时,会用到类型glob的文件句柄部分,这只是一种传递标识符STDIN并让其他东西将其用作文件句柄的方法。
您可以将此视为传递已命名的标准文件句柄的一种方式。
read将文件句柄(或对typeglob的引用)作为其第一个参数。
在python中,您可以执行类似于sys.stdin.read(...)的操作。

yzuktlbb

yzuktlbb2#

以下是通常可以使用的文件句柄:

  • 一个IO对象(*STDIN{IO}
  • 包含IO对象的glob(*STDIN
  • 对包含IO对象的glob的引用(\*STDIN
  • 包含IO对象的glob的名称("STDIN"

需要文件句柄的内置运算符允许您在提供glob时省略*。例如,read( FH, ... )表示read( *FH, ... )
期望文件句柄的内置函数应该接受所有这些。因此,您可以使用以下任何一种方法:

  • read( *STDIN{IO}, ... )
  • read( STDIN, ... )
  • read( *STDIN, ... )
  • read( \*STDIN, ... )
  • read( "STDIN", ... ) .

它们会产生同样的效果。
第三方库可能接受globs和对globs的引用,它们也应该接受IO对象。我希望最少支持以字符串形式提供名称。您的里程可能会有所不同。
引用一个glob(\*FH)不会出错,因为open( my $fh, ... )就是这样产生的。

相关问题