如果我有一個函數可能會傳遞一個文件名或各種文件句柄或typeglobs,函數如何區分這些參數 - 包括告訴區別,例如,在*DATA
和*STDIN
之間?Perl子程序如何區分文件名,文件handes,* DATA和* STDIN?
更新的代碼,根據迄今收到的答案謝謝大家。
use strict;
use warnings;
use FileHandle;
sub file_thing_type {
my ($f) = shift;
my $type;
my $r = ref $f;
if ($r eq 'GLOB' or ref(\$f) eq 'GLOB'){
# Regular and built-in file handles.
my $fn = fileno $f;
if (defined $fn){
my %built_in = (
'STDIN' => fileno(*STDIN),
'STDOUT' => fileno(*STDOUT),
'STDERR' => fileno(*STDERR),
'DATA' => fileno(*DATA),
);
for my $k (keys %built_in){
if (defined $built_in{$k} and $built_in{$k} == $fn){
$type = $k;
last;
}
}
$type = 'regular file handle' unless defined $type;
}
else {
$type = 'non-IO glob';
}
}
elsif ($r){
# A reference of some kind.
$type = $r;
# Might be an IO object. Has it been opened?
{
no warnings 'unopened';
$type .= ' opened' if -f $f;
}
}
else {
# File name or just some other value?
$type = -f $f ? 'file name' : 'other';
}
return $type;
}
open(my $h, '<', $0) or die $!;
printf "%12s => %s\n",
$_->[0],
file_thing_type($_->[1])
for (
[ 'handle', $h ], # regular file handle
[ 'DATA', *DATA ], # DATA if source has DATA section; else non-IO glob
[ 'STDIN', *STDIN ], # STDIN
[ 'STDOUT', *STDOUT ], # STDOUT
[ 'STDERR', *STDERR ], # STDERR
[ 'FOO', *FOO, *FOO ], # non-IO glob
[ 'FileHandle', FileHandle->new ], # FileHandle
[ 'FileHandle', FileHandle->new($0) ], # FileHandle opened
[ 'file name', $0 ], # file name
[ 'not file', '' ], # other
[ 'misc', {bar=>1} ], # HASH
);
__END__
它們都是文件句柄。你究竟想要測試什麼? 您可以使用手柄上的「-t」測試來檢查它是否來自/去往終端(TTY),這通常對於STDIN和STDOUT是正確的,除非管道連接。 – amphetamachine 2010-02-22 03:36:42
請讓我們知道你想做什麼的更廣泛的背景。爲什麼你需要能夠DATA'和'STDIN'之間'區別? – 2010-02-22 14:37:55
@gbacon說實話,我不能肯定。我工作的事昨天深夜,並認爲這可能有助於能夠區分。然後,我注意到,數據::自卸車能夠分開(排序)告訴他們,所以我想這個問題可能有一個簡單的答案,我提出它左右。從那時起,我對我的項目思維的發展,所以現在我們只是到好奇。 :) – FMc 2010-02-22 14:43:03