checking for filehandle

Y

Yakov

Let's say I want to check whether $fh is a filehandle. Take 1
is to: defined(fileno($fh)). Perfect solution ? No. When $fh is a
tied-filehandle, $fh may not have real filedescriptor behind it
( for example, it sends output to the shared memory ).

How do I check for $fh being a filehandle, the check would work
even for tied filehandles that do not have real filedescriptor ?

Thanks
Yakov
 
A

anno4000

Yakov said:
Let's say I want to check whether $fh is a filehandle. Take 1
is to: defined(fileno($fh)). Perfect solution ? No. When $fh is a
tied-filehandle, $fh may not have real filedescriptor behind it
( for example, it sends output to the shared memory ).

How do I check for $fh being a filehandle, the check would work
even for tied filehandles that do not have real filedescriptor ?

In general it is hard to say for sure what a tied variable will respond
to. You can use tied() to access the underlying object and make
plausibility tests:

my $is_fh = tied( $h) && tied( $h)->isa( 'File::Handle');

or

my $is_fh = tied( $h) && tied( $h)->can( 'READ');

or similar. Both can go wrong, but will give the correct answer in most
cases.

In Perl 10 there will be UNIVERSAL::DOES that addresses this kind of
problem.

Anno
 
Y

Yakov

In general it is hard to say for sure what a tied variable will respond
to. You can use tied() to access the underlying object and make
plausibility tests:

my $is_fh = tied( $h) && tied( $h)->isa( 'File::Handle');

or

my $is_fh = tied( $h) && tied( $h)->can( 'READ');

or similar. Both can go wrong, but will give the correct answer in most
cases.

Ok thanks. This seems to be the check:

defined(fileno($fh)) || (tied( $fh) && tied($fh)-
can( 'TIEHANDLE' ))

Looks ok ?

Yakov
 
A

anno4000

Yakov said:
Ok thanks. This seems to be the check:

defined(fileno($fh)) || (tied( $fh) && tied($fh)-

Looks ok ?

Yes. In fact, testing for "TIEHANDLE" should be pretty much watertight.

Anno
 
D

Dr.Ruud

Michele Dondi schreef:
anno:

5.10, Anno! People are still ranting about 6... I wonder on which
isolinear chip 10 will be supposed to run! :)

I prefer to have it called Perl5 version 10. Perl5 will not die, Perl6
will have her own life.

Perl6 is a totally different language that again includes a lot of
goodies from other tools and languages (such as Perl5), just as Perl
originally did with awk, sed etc.
 
B

Ben Morrow

Quoth (e-mail address removed)-berlin.de:
Yes. In fact, testing for "TIEHANDLE" should be pretty much watertight.

Not at all. Consider:

#!/usr/bin/perl -l

use Tie::Handle;
use Tie::Scalar;
use Scalar::Util qw/openhandle/;
use IO::Scalar;

{
package Foo;

use base qw/Tie::StdScalar Tie::StdHandle/;
}

sub is_a_handle {
return 1 if defined fileno $_[0];
return tied($_[0]) and tied($_[0])->can('TIEHANDLE');
}

my $x = \do { local *F };
tie *$x, 'Tie::StdHandle';

tie my $y, 'Foo';

my $tmp;
my $z = IO::Scalar->new(\$tmp);

print '$x is ', openhandle($x) ? 'a handle' : 'not a handle';
print '$y is ', openhandle($y) ? 'a handle' : 'not a handle';
print '$y will appear to be ',
is_a_handle($y) ? 'a handle' : 'not a handle';
print '$z is ', openhandle($z) ? 'a handle' : 'not a handle';
print '$z will appear to be ',
is_a_handle($z) ? 'a handle' : 'not a handle';

__END__

~/src/perl% perl tiehandle
$x is a handle
$y is not a handle
$y will appear to be a handle
$z is a handle
Can't locate object method "FILENO" via package "IO::Scalar" at
tiehandle line 15.

The correct answer is Scalar::Util::eek:penhandle.

Ben
 
A

anno4000

Ben Morrow said:
Quoth (e-mail address removed)-berlin.de:

Not at all. Consider:

[consideration of false positives snipped]

You are right, I wasn't thinking of false positives at all.
The correct answer is Scalar::Util::eek:penhandle.

Thanks for pointing it out. I hadn't noticed this one, but
Scalar::Util is full of tests that you don't use every day,
but are hard to get right when you need them.

blessed, isweak, isvstring, looks_like_number, openhandle,
readonly, reftype, tainted are all more or less in that category.

Anno

Anno
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,007
Latest member
obedient dusk

Latest Threads

Top