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?

A whole module that does what I want ... in some cases I'd want it to return true.

That is only the case if you define "what you want" as: "What my newly minted module does."

But, what does a.n.other user actually need? And does your is_filehandle() actually supply it?

That is, someone is writing a module that accepts a "file handle" as a input argument, and they want to know if what they've been given, is acceptable for their purpose. That means they can either read from it; write to it; or both. And your module fails to detect that information.

#! perl -slw use strict; use IO::Detect qw[ is_filehandle ]; sub funcTakesIO1 { my $fh = shift; if( is_filehandle( $fh ) ) { print $fh 'Bang!'; } return; } sub funcTakesIO2 { my $fh = shift; if( is_filehandle( $fh ) ) { return <$fh>; } return; } eval { funcTakesIO1( \*STDIN ); } or warn "IO::Detect detected the wrong thing"; eval { funcTakesIO2( \*STDOUT ); } or warn "IO::Detect detected the wrong thing"; __END__ C:\test>junk5 Filehandle STDIN opened only for input at C:\test\junk5.pl line 9. IO::Detect detected the wrong thing at C:\test\junk5.pl line 24. Filehandle STDOUT opened only for output at C:\test\junk5.pl line 18. IO::Detect detected the wrong thing at C:\test\junk5.pl line 28.

What the user actually requires in that situation is something like siphylis' Filehandle::Fmode, which has been around for a few years and effectively renders your module redundant.


With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.

The start of some sanity?

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

    Or if the disk is full; or if it's an IO::Socket::INET handle where the network connection has dropped; etc. Detecting anything that could possibly go wrong with a filehandle is not my aim. The primary use case for IO::Detect is, as stated in the documentation, writing functions that can accept either a file name or a file handle.

    For example parse($file) - I want it to accept a filehandle, and I want it to accept a filename. If someone passes a filehandle in write-only mode then that's their own fault and I'm quite happy for it to blow up in their face.

    As far as detecting whether a file handle is read or write, I may add that functionality if I come across a situation where it would be useful.

    Re FileHandle::Fmode...

    $ perl -MFileHandle::Fmode=is_FH -MIO::All -E'say is_FH(IO::All->new(" +/dev/null"))' 0
    perl -E'sub Monkey::do{say$_,for@_,do{($monkey=[caller(0)]->[3])=~s{::}{ }and$monkey}}"Monkey say"->Monkey::do'
      I'm quite happy for it to blow up in their face.

      So, what purpose does your module serve?

      In some wholly arbitrary subset of cases, it allows your users to avoid faulting; but in other, equally likely cases it doesn't.

      And what does that mean for the callers of the modules that use your module?

      It means that for some failures, instead of detecting all possible errors by trapping exceptions like this:

      eval { funcThatPassesAFileHandleOrName( $arg ); } or do_something();

      They now have to do something like:

      eval { unless( funcThatPassesAFileHandleOrName( $arg ) ) { doSomething(); } } or doSomething();

      They can't omit the eval because -- as you've just admitted -- there are some common cases that you simply make no attempt to catch.

      And what do they -- the users of modules that use your module to validate these parameters -- gain from its use? That is, what action can they take in that arbitrary subset of cases where your module detects an error that would normally raise an exception?

      Can they -- at runtime -- invent a different filename that is valid? Or pluck a different filehandle out of the air that passes the test and use that instead?

      No. All they can do is either issue a warning and move onto the next filehandle -- assuming that is the logic of the program -- or they can die with an error message. But does your module report enough information to allow them to report why it failed? Illegal filename; or file doesn't exist; or file is protected against them; or the filehandle was real, but has been closed; or was never opened; or ... ??? No. All they can do is issue some vague "something was wrong" message.

      Whereas, if the called module has just gone ahead and attempted to use the argument as passed for whatever IO operation it was destined, the runtime would have detected the problem and raised an exception containing a very clear error value/string that would actually help the user.

      And if the logic of the program was such that it could continue (say; with the next file(handle)), then the user's eval -- that he will still need to employ anyway -- would have both caught it and provided the precise error message to the caller for logging.

      All your module does is convert a subset of useful exceptions into a vague and non-descriptive boolean false!

      The net result is more complexity for less than no gain.

      Your module is there, and nothing I say will cause it to un-exist. There is no reason for you to continue to defend its existence. But maybe my missive here will cause a few readers to consider thinking through the purpose of their modules to their logical conclusions, rather than being so quick off the mark to throw something together and whack it up on CPAN.

      CPAN's greatest limitations are a) its size; b) its quality. Finding the good stuff amongst the ill-thought through, gets harder every day,

      Width is no substitute for quality.


      With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
      Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
      "Science is about questioning the status quo. Questioning authority".
      In the absence of evidence, opinion is indistinguishable from prejudice.

      The start of some sanity?

        "So, what purpose does your module serve?

        "In some wholly arbitrary subset of cases, it allows your users to avoid faulting; but in other, equally likely cases it doesn't."

        As I previously stated (in Re^4: Best way to check if something is a file handle? and in the IO::Detect pod) it is not the aim of the module to protect against exceptions. That's what eval is for. The aim is purely to be able to write functions that can accept either a file handle or a file name. This sort of thing...

        sub parse { my $file = shift; if (is_filehandle $file) { # do stuff } elsif (is_filename $file) { open my $fh, '<', $file; return parse($fh); } }
        perl -E'sub Monkey::do{say$_,for@_,do{($monkey=[caller(0)]->[3])=~s{::}{ }and$monkey}}"Monkey say"->Monkey::do'