Beefy Boxes and Bandwidth Generously Provided by pair Networks
The stupid question is the question not asked
 
PerlMonks  

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

by Athanasius (Monsignor)
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.

HTH,

Athanasius <°(((><contra mundum


Comment on Re^3: Best way to check if something is a file handle?
Download Code
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.


      Dave

        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?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://980686]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others musing on the Monastery: (5)
As of 2014-09-21 18:21 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    How do you remember the number of days in each month?











    Results (173 votes), past polls