Si j'ai une fonction qui pourrait être passée un nom de fichier ou plusieurs handles de fichiers ou typeglobs, comment la fonction peut-elle distinguer parmi ces arguments - y compris la différence, par exemple, entre *DATA
et *STDIN
?Comment un sous-programme Perl peut-il faire la distinction entre les noms de fichiers, les fichiers, * DATA et * STDIN?
Code mis à jour, basé sur les réponses reçues jusqu'ici Merci, tout le monde.
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__
Ce sont toutes des poignées de fichiers. Qu'est-ce que vous essayez exactement de tester? Vous pouvez utiliser le test "-t" sur la poignée pour vérifier si elle provient de/va vers un terminal (TTY), ce qui sera normalement vrai pour STDIN et STDOUT, à moins d'être acheminé. – amphetamachine
S'il vous plaît laissez-nous savoir le contexte plus large de ce que vous voulez faire.Pourquoi devez-vous être capable de distinguer entre 'DATA' et' STDIN'? –
@gbacon En toute honnêteté, je ne suis pas certain. Je travaillais sur quelque chose en retard la nuit dernière et je pensais que cela pourrait aider à être capable de distinguer. Puis j'ai remarqué que Data :: Dumper était capable de les différencier (sorte de), donc j'ai pensé que la question pourrait avoir une réponse simple et je l'ai posée sur SO. Depuis lors, ma réflexion sur mon projet a évolué, alors maintenant nous sommes juste à la curiosité. :) – FMc