Beefy Boxes and Bandwidth Generously Provided by pair Networks
Clear questions and runnable code
get the best and fastest answer

Re^3: Best way to check if something is a file handle?

by Athanasius (Chancellor)
on Jul 09, 2012 at 10:18 UTC ( #980686=note: print w/replies, xml ) Need Help??

in reply to Re^2: Best way to check if something is a file handle?
in thread Best way to check if something is a file handle?

Not really surprising, since, according to perldoc,

UNIVERSAL is the base class from which all blessed references inherit

that is, the can method applies only to objects.

Would something like this do?

#! perl use strict; use warnings; my $in_file = 'temp1.txt'; # this must exist my $outfile = 'temp2.txt'; my $arrayref = []; open(my $in, '<', $in_file) or die "Cannot open file '$in_file' for r +eading: $!"; open(my $out, '>', $outfile) or die "Cannot open file '$outfile' for w +riting: $!"; can_write( $in_file, $in); can_write( $outfile, $out); can_write('$arrayref', $arrayref); close($in) or die "Cannot close file '$in_file': $!" +; close($out) or die "Cannot close file '$outfile': $!" +; sub can_write { my ($name, $fh) = @_; my $result = eval { no warnings; print $fh '' }; printf "$name %s write\n", ($result ? 'can' : 'cannot'); } __END__ temp1.txt cannot write temp2.txt can write $arrayref cannot write

Update: The CPAN module FileHandle::Fmode by Sisyphus/syphilis may also be worth investigating, although it too appears not to work with IO::All objects.


Athanasius <°(((><contra mundum

Replies are listed 'Best First'.
Re^4: Best way to check if something is a file handle?
by tobyink (Abbot) on Jul 09, 2012 at 10:42 UTC

    The strange thing is that although $fh->can('close') doesn't return true, it also doesn't complain about there being no can method, whereas $fh->might('close') does complain about a missing might method. So it is, in some manner being treated as an object that kinda half implements the UNIVERSAL interface.

    Writing the empty string to a handle is quite a nice solution I suppose, but there may be some tied interfaces where printing even the empty string has side-effects. :-(

    And as it happens I'm actually more interested in reading than writing.

    perl -E'sub Monkey::do{say$_,for@_,do{($monkey=[caller(0)]->[3])=~s{::}{ }and$monkey}}"Monkey say"->Monkey::do'

      eval{} some innocuous operation such as $fh->format_name and check if an error has been generated. That takes 'duck typing' to its logical end; A filehandle can "format_name", so let's "format_name" and see if we get an error.

      However, you have to keep in mind that if $fh contains a glob that holds a string, that string will silently try to convert itself to a filehandle.

      For example: $something = 'STDOUT'; *someglob = $something; $fh = \*someglob; $fh->format_name; will be accepted just fine, because $fh contains a reference to a glob that holds the STDOUT filehandle, even though it was just a string only two operations ago. In fact the third layer of indirection isn't even needed; *someglob also contains a filehandle, of course. Perl would be equally happy with *someglob->format_name. And in fact, even $something->format_name is fine with Perl; as long as the string looks like a known filehandle, it's fine.

      On the other hand, $something = 'frobcinate'; $something->format_name; will throw an exception unless you've opened a filehandle named *frobcinate.

      This may be a terrible oversimplification that fails to work in some important cases. Certainly it would fail if $something were blessed into a class that is nothing like a filehandle except that it has a method named format_name.


        It also fails for IO::All, but yes, format_name seems to be a good choice of an innocuous method for evaling.

        I don't think there's any silver bullet. :-(

        perl -E'sub Monkey::do{say$_,for@_,do{($monkey=[caller(0)]->[3])=~s{::}{ }and$monkey}}"Monkey say"->Monkey::do'

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://980686]
[marto]: believe it or not this is a SPAM account :P
[Discipulus]: it seems a legitimate one.. grin ..

How do I use this? | Other CB clients
Other Users?
Others making s'mores by the fire in the courtyard of the Monastery: (9)
As of 2018-05-22 12:18 GMT
Find Nodes?
    Voting Booth?