如果我有一个可能传递文件名或各种文件句柄或typeglobs的函数,那么函数如何区分这些参数 - 包括告诉差异,例如*DATA
和{{1 }}?
根据目前为止收到的答案更新了代码谢谢大家。
*STDIN
答案 0 :(得分:2)
更新:区分可能分配给*DATA
或*STDIN
整数的变量的问题是fileno
的工作:
sub data_or_stdin { my $x = shift; if (fileno($x) == fileno(DATA)) { return "DATA"; } elsif (fileno($x) == fileno(STDIN)) { return "STDIN"; } else { return "NEITHER"; } } print "DATA: ", data_or_stdin(*DATA), "\n"; print "STDIN: ", data_or_stdin(*STDIN), "\n"; open(ZZZ, ">>", "zzz"); close ZZZ; open(ZZZ, "<", "zzz"); print "ZZZ: ", data_or_stdin(*ZZZ), "\n"; close ZZZ; open($fh, "<", "zzz"); print "\$fh=ZZZ: ", data_or_stdin($fh), "\n"; close $fh; $fh = *DATA; print "\$fh=DATA: ", data_or_stdin($fh), "\n"; $fh = *STDIN; print "\$fh=STDIN: ", data_or_stdin($fh), "\n"; __END__ stuff;
$ perl data_or_stdin.pl DATA: DATA STDIN: DATA ZZZ: NEITHER $fh=ZZZ: NEITHER $fh=DATA: DATA $fh=STDIN: DATA
如果$f
是文件句柄,则ref $f
或ref \$f
将为"GLOB"
如果$f
是标量,则ref \$f
将为"SCALAR"
。
sub filehandle_or_scalar {
my $x = shift;
if (ref $x eq "GLOB" || ref \$x eq "GLOB") {
return "filehandle";
} elsif (ref \$x eq "SCALAR") {
return "scalar";
} else {
return "not filehandle or scalar";
}
}
print "STDIN: ", filehandle_or_scalar(*STDIN), "\n";
print "\$_: ", filehandle_or_scalar($_), "\n";
open($fh, ">", "zzz");
print "\$fh: ", filehandle_or_scalar($fh), "\n";
print "string: ", filehandle_or_scalar('file.txt'), "\n";
print "ref: ", filehandle_or_scalar(\$x), "\n"
###########################################
$ perl filehandle_or_scalar.pl
STDIN: filehandle
$_: scalar
$fh: filehandle
string: scalar
ref: not filehandle or scalar
答案 1 :(得分:1)
您可以在字符串文件句柄上使用模式匹配* STDIN,* DATA等...
if ($f =~ /\bSTDIN$/) {
return "STDIN";
} elsif ($f =~ /\bDATA$/) {
return "DATA";
}
哈基,但可能就够了......
答案 2 :(得分:1)
mobrule的方法看起来很有希望:
perl -E 'open $fh, "<", "/dev/null"; say ref $fh;'
将输出GLOB
。但是,
perl -E 'say ref \*FOO;'
“真正的”文件句柄也将具有与之关联的文件描述符
您可以使用fileno
确定它:
perl -MData::Dumper -E 'open $fh, "<", "/dev/null"; say Data::Dumper::Dumper([fileno $fh, fileno \*STDIN, fileno \*FOO])'
将输出如下内容:
$VAR1 = [
3,
0,
undef
];
您可以使用它来告诉正在用于文件I / O的GLOB 一个不是。在UNIX系统上,标准输入流按照惯例与文件描述符0 相关联。
我想到的另一件事是一个与a相关的类
文件句柄。这些需要实现您的特定接口
可以测试使用can
。请参阅平局VARIABLE,CLASSNAME,LIST
有关此界面的详细信息,请参阅 perlfunc 。