There are several possible approaches to this. One is to assume that anything passed is either a simple string or an appropriate handle, and just choose between the two:

if (ref $param) { # it isn't a simple string, assume it is a filehandle $fh = $param; } else { open $fh, "<", $param or die "$param: $!"; }

A second approach is to require one of a set of specific types, but this disallows inherited types:

my $type = ref $param; if (!$type) { # it's a simple scalar } elsif ($type eq 'GLOB') { # an unblessed GLOB ref } elsif ($type eq 'IO::Handle') { # it's a non-overloaded IO::Handle } else { ... }

(When using this approach or some of the others, it is also worth being aware of Scalar::Util which has methods blessed() and reftype() for finer distinctions than ref() offers.)

A third approach is to look for inherited types using isa():

if (!ref $param) { # scalar } elsif (ref($param) eq 'GLOB') { # GLOB } elsif ($param->isa('IO::Handle')) { # is, or inherits from, IO::Handle } else { ... }

Yet another possibility is to test for the features you need with can(); say the only thing you need to be able to do with it is readline you could say:

if (!ref $param) { # scalar } elsif ($param->can('readline')) { # who knows what it is? But it supports a readline method ... } else { ... }

The various approaches all have different benefits and drawbacks, and which suits you best will depend on the specifics of your application. In general, though, I prefer the first: check as little as possible early on, and let the later code fail with a message such as:

Can't locate method 'readline' via package 'IO::StrangeHandle'

In particular, this approach is the least likely to stop someone using your routine with some object that they know should work, but due to some strangeness in how it describes itself might fail to match one of the other checks.

Hugo


In reply to Re: Accepting either a filename or a handle by hv
in thread Accepting either a filename or a handle by fizbin

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.