Si tengo una función que puede pasar un nombre de archivo o varios manejadores de archivo o typeglobs, ¿cómo puede la función distinguir entre estos argumentos, incluyendo decir la diferencia, por ejemplo, entre *DATA
y *STDIN
?¿Cómo puede distinguir una subrutina Perl entre los nombres de archivo, las herramientas de archivo, * DATA y * STDIN?
Código actualizado, basado en las respuestas recibidas hasta ahora Gracias a todos.
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__
Son todos manejadores de archivo. ¿Qué estás tratando de probar exactamente? Puede usar la prueba "-t" en el mango para verificar si se trata de un terminal (TTY), lo que normalmente será cierto para STDIN y STDOUT, a menos que esté conectado por cañería. – amphetamachine
Háganos saber el contexto más amplio de lo que quiere hacer.¿Por qué necesita poder distinguir entre 'DATA' y' STDIN'? –
@gbacon Honestamente, no estoy seguro. Estuve trabajando en algo anoche y pensé que sería útil poder distinguir. Luego noté que Data :: Dumper podía diferenciarlos (más o menos), así que pensé que la pregunta podría tener una respuesta simple y la planteé en SO. Desde entonces, mi pensamiento acerca de mi proyecto ha evolucionado, así que ahora estamos solo por curiosidad. :) – FMc