http://www.perlmonks.org?node_id=980708


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

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

Replies are listed 'Best First'.
Re^6: Best way to check if something is a file handle?
by tobyink (Canon) on Jul 09, 2012 at 16:25 UTC

    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'