我正在使用select返回的文件句柄。
有关select的文档为:
- 选择
返回当前选定的文件句柄。
我有一段代码,可以打印一些数据,通常无需任何重定向即可执行。但是有一个用例,其中使用select将打印输出重定向到文件。
在这段代码中,我需要使用当前选择的文件句柄。我尝试了以下代码片段:
my $fh = select;
print $fh "test\n";
我写了一个简短的测试程序来演示我的问题:
#!/usr/bin/perl
use strict;
use warnings;
sub test
{
my $fh=select;
print $fh "@_\n";
}
my $oldfh;
# this works :-)
open my $test1, "> test1.txt";
$oldfh = select $test1;
test("test1");
close select $oldfh if defined $oldfh;
#this doesn't work. :-(
# Can't use string ("main::TEST2") as a symbol ref while "strict refs" in use
open TEST2,">test2.txt";
$oldfh = select TEST2;
test("test2");
close select $oldfh if defined $oldfh;
#this doesn't work, too. :-(
# gives Can't use string ("main::STDOUT") as a symbol ref while "strict refs" in use at
test("test");
似乎,select不会返回对文件句柄的引用,而是一个包含文件句柄名称的字符串。
我该怎么做才能始终从select的返回值中获得可用的文件句柄?
P.S。我需要将此文件句柄作为OutputFile传递给XML :: Simple的XMLout()。
答案 0 :(得分:3)
答案 1 :(得分:3)
只需使用
print XMLout(...);
看来,select不会返回对文件句柄的引用,而是一个包含文件句柄名称的字符串。
它确实可以返回一个普通的普通字符串。
>perl -MDevel::Peek -E"Dump(select())"
SV = PV(0x6cbe38) at 0x260e850
REFCNT = 1
FLAGS = (PADTMP,POK,pPOK)
PV = 0x261ce48 "main::STDOUT"\0
CUR = 12
LEN = 24
但是作为Perl的文件句柄是完全可以接受的。 Perl作为文件句柄接受四件事:
对IO对象的引用。
>perl -e"my $fh = *STDOUT{IO}; CORE::say($fh 'foo');"
foo
一个包含对IO对象的引用的glob。
>perl -e"my $fh = *STDOUT; CORE::say($fh 'foo');"
foo
对glob的引用,其中包含对IO对象的引用。
>perl -e"my $fh = \*STDOUT; CORE::say($fh 'foo');"
foo
对glob的“符号引用”,其中包含对IO对象的引用。
>perl -e"my $fh = 'STDOUT'; CORE::say($fh 'foo');"
foo
但是,这种类型在严格的引用下不起作用。
>perl -Mstrict -e"my $fh = 'STDOUT'; CORE::say($fh 'foo');"
Can't use string ("STDOUT") as a symbol ref while "strict refs" in use at -e line 1.
我该怎么做才能始终从select的返回值中获得可用的文件句柄?
如上所述,它已经返回了一个完美可用的文件句柄。如果XMLout
不支持,则是XMLout
中的错误。您可以按照以下方法解决它:
my $fh = select();
if (!ref($fh) && ref(\$fh) ne 'GLOB') {
no strict qw( refs );
$fh = \*$fh;
}
这也可用于使手柄在严格的环境中可用
与XML :: Simple一样糟糕,它读取XML时,生成XML的速度要差一百万倍。参见Why is XML::Simple Discouraged?。
如果要修改XML,请考虑XML::LibXML或XML::Twig。
如果要生成XML,请考虑XML::Writer。
答案 2 :(得分:0)
首先,您不应该使用XML :: Simple,因为它将需要大量工作来确保您的输出将生成一致的XML。至少确保您使用的是适当的ForceArray
参数。
为什么不使用文件处理恶作剧,为什么不使用更简单的
print XMLout($data, %options);
...而不是尝试传递默认文件句柄?