Wenn ich eine Funktion habe, der ein Dateiname oder verschiedene Dateihandles oder typeglobs übergeben werden könnten, wie kann die Funktion zwischen diesen Argumenten unterscheiden - einschließlich der Unterscheidung zwischen zB *DATA
und *STDIN
?Wie kann eine Perl-Subroutine zwischen Dateinamen, Dateihandeln, * DATA und * STDIN unterscheiden?
Aktualisierter Code, basierend auf bisher erhaltenen Antworten Danke, alle.
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__
Sie sind alle Dateigriffe. Was genau willst du testen? Sie können den "-t" -Test auf dem Handle verwenden, um zu überprüfen, ob es von einem Terminal (TTY) kommt oder zu ihm geht, was normalerweise für STDIN und STDOUT gilt, sofern nicht piped. – amphetamachine
Bitte teilen Sie uns den weiteren Kontext dessen, was Sie tun möchten.Warum müssen Sie zwischen "DATA" und "STDIN" unterscheiden können? –
@gbacon Ehrlich gesagt bin ich mir nicht sicher. Ich habe letzte Nacht an etwas spät gearbeitet und dachte, es könnte helfen, etwas unterscheiden zu können. Dann fiel mir auf, dass Data :: Dumper in der Lage war, sie (irgendwie) voneinander zu unterscheiden, also dachte ich, die Frage könnte eine einfache Antwort haben und ich stellte sie auf SO. Seither hat sich mein Denken über mein Projekt weiterentwickelt, und jetzt sind wir nur noch neugierig. :) – FMc