GLOB vs IO::Handle

Discussion in 'Perl Misc' started by bill, Jan 11, 2005.

  1. bill

    bill Guest

    I want to write a sub that takes either a string which is interpreted
    as a filename to be opened and read, or an open read handle. The
    question is how to test for the latter? At first I thought I'd
    just test

    ref $_[0] eq 'GLOB';

    but then I realized that $_[0] could be an object of type IO::Handle,
    or something like it. And besides, even if $in is a variable of
    type GLOB, this does not ensure that <$in> is a valid operation.
    After convincing myself that testing for GLOBness was *not* the
    thing to do, I thought I could test

    UNIVERSAL::can($_[0], 'getline');

    but I soon discovered that if $in is defined by

    open (my $in, 'foobar') or die "Can't read foobar: $!\n";

    then UNIVERSAL::can($my, 'getline') fails.

    By this point I get the distinct feeling that I just don't know
    enough about this wheel to mess around with reinventing it. What's
    the tried-and-true idiom for doing what I want to do?

    Thanks!

    bill
    bill, Jan 11, 2005
    #1
    1. Advertising

  2. bill <> wrote in news:cs0i0i$p1g$:

    > I want to write a sub that takes either a string which is interpreted
    > as a filename to be opened and read, or an open read handle. The
    > question is how to test for the latter?


    I personally would not go down that route, but rather pass two arguments to
    the sub. The first would indicate whether a file handle or a filename was
    passed:

    #! /usr/bin/perl

    # Untested pseudo-code below

    use strict;
    use warnings;

    sub myread {
    my ($type, $arg) = @_;
    if($type eq 'filename') {
    # filename passed
    } elsif($_[0] eq 'filehandle') {
    # filehandle passed
    } else {
    # programmer error
    }
    }

    myread(filename => 'test.txt');
    myread(filehandle => $fh);
    myread(filehandle => \*STDIN);


    Sinan.
    A. Sinan Unur, Jan 11, 2005
    #2
    1. Advertising

  3. bill

    Guest

    bill <> wrote:
    > I want to write a sub that takes either a string which is interpreted
    > as a filename to be opened and read, or an open read handle. The
    > question is how to test for the latter?


    You don't. You gave the user two options, a plain old scalar, whose string
    value is used as a filename, or a handle. Therefore, if it isn't a plain
    old scalar, it must be a handle. Use it like a handle. If they send in
    something that is neither one of these things, they should get bitched at.
    But just let perl do the bitching, at the point where the whatever-it-is is
    used as a handle.

    Xho

    --
    -------------------- http://NewsReader.Com/ --------------------
    Usenet Newsgroup Service $9.95/Month 30GB
    , Jan 11, 2005
    #3
  4. bill

    Anno Siegel Guest

    bill <> wrote in comp.lang.perl.misc:
    >
    >
    >
    > I want to write a sub that takes either a string which is interpreted
    > as a filename to be opened and read, or an open read handle. The


    [...]

    > By this point I get the distinct feeling that I just don't know
    > enough about this wheel to mess around with reinventing it. What's
    > the tried-and-true idiom for doing what I want to do?


    if ( defined fileno $x ) {
    # it's an open file handle
    }

    Anno
    Anno Siegel, Jan 11, 2005
    #4
  5. wrote:

    > bill <> wrote:
    >
    >>I want to write a sub that takes either a string which is interpreted
    >>as a filename to be opened and read, or an open read handle. The
    >>question is how to test for the latter?

    >
    >
    > You don't. You gave the user two options, a plain old scalar, whose string
    > value is used as a filename, or a handle. Therefore, if it isn't a plain
    > old scalar, it must be a handle. Use it like a handle. If they send in
    > something that is neither one of these things, they should get bitched at.
    > But just let perl do the bitching, at the point where the whatever-it-is is
    > used as a handle.


    It is worth pointing out that a scalar varialble can be one of there
    things: a plain old scalar, a reference or a (fake) GLOB.

    Now the use of fake GLOBs rather than GLOBrefs is frowned upon by me but
    if you want to leave the option open you need check that a scalar
    variable is a plain old scalar thus:

    ref(\$thing) eq 'SCALAR'

    or if you are feeling really pendantic...

    !ref($thing) && ref(\$thing) ne 'GLOB'

    Of course this does not cope with objects that are can be treated as
    strings because they overload "".

    Even if you could cope with that what would you do with object that can
    be treates as both strings and filehandles?
    Brian McCauley, Jan 11, 2005
    #5
  6. bill

    bill Guest

    In <cs0v7v$51f$-Berlin.DE> -berlin.de (Anno Siegel) writes:

    >bill <> wrote in comp.lang.perl.misc:
    >>
    >>
    >>
    >> I want to write a sub that takes either a string which is interpreted
    >> as a filename to be opened and read, or an open read handle. The


    >[...]


    >> By this point I get the distinct feeling that I just don't know
    >> enough about this wheel to mess around with reinventing it. What's
    >> the tried-and-true idiom for doing what I want to do?


    > if ( defined fileno $x ) {
    > # it's an open file handle
    > }


    Way cool... Is there a simpler way to deal with an open non-read
    handle than to wrap everything in an eval, redefine $SIG{__WARN__}
    to make warnings fatal, analyze $@ afterwards, and die if <$x> was
    attempted on an open non-read handle?

    bill
    Perl Sophomore
    bill, Jan 11, 2005
    #6
  7. bill

    Anno Siegel Guest

    bill <> wrote in comp.lang.perl.misc:
    > In <cs0v7v$51f$-Berlin.DE>
    > -berlin.de (Anno Siegel) writes:
    > >bill <> wrote in comp.lang.perl.misc:


    > >> I want to write a sub that takes either a string which is interpreted
    > >> as a filename to be opened and read, or an open read handle. The

    >
    > >[...]

    >
    > >> By this point I get the distinct feeling that I just don't know
    > >> enough about this wheel to mess around with reinventing it. What's
    > >> the tried-and-true idiom for doing what I want to do?

    >
    > > if ( defined fileno $x ) {
    > > # it's an open file handle
    > > }

    >
    > Way cool... Is there a simpler way to deal with an open non-read
    > handle than to wrap everything in an eval, redefine $SIG{__WARN__}
    > to make warnings fatal, analyze $@ afterwards, and die if <$x> was
    > attempted on an open non-read handle?


    With sufficiently recent Perl you can make the warning fatal without
    %SIG:

    eval {
    use warnings FATAL => 'io';
    my $s = <$x>;
    };
    my $readable = not $@;

    The main problem with this approach is, if the file *is* readable, you
    have read (lost) a line from it. You will usually have to thread it back
    into the read loop, or use tell/seek to restore the position.

    I don't know of a simple method to ask a file handle if it's readable.
    Normally, you know what type of handle to expect. If you don't, it's
    probably time for a re-design so you do. The contortions of finding
    out later are not worth the effort.

    Anno
    Anno Siegel, Jan 11, 2005
    #7
  8. bill

    Sisyphus Guest

    Anno Siegel wrote:

    >
    >>By this point I get the distinct feeling that I just don't know
    >>enough about this wheel to mess around with reinventing it. What's
    >>the tried-and-true idiom for doing what I want to do?

    >
    >
    > if ( defined fileno $x ) {
    > # it's an open file handle
    > }
    >
    > Anno


    from 'perldoc -f fileno':
    (Filehandles connected to memory objects via new features of
    "open" may return undefined even though they are open.)

    I don't know if/how that impacts on the OP's requirements - or on Anno's
    solution, for that matter.

    Cheers,
    Rob



    --
    To reply by email u have to take out the u in kalinaubears.
    Sisyphus, Jan 12, 2005
    #8
  9. Sisyphus wrote:

    > Anno Siegel wrote:
    >
    >>
    >>> By this point I get the distinct feeling that I just don't know
    >>> enough about this wheel to mess around with reinventing it. What's
    >>> the tried-and-true idiom for doing what I want to do?

    >>
    >>
    >>
    >> if ( defined fileno $x ) {
    >> # it's an open file handle
    >> }
    >>
    >> Anno

    >
    >
    > from 'perldoc -f fileno':
    > (Filehandles connected to memory objects via new features of
    > "open" may return undefined even though they are open.)


    I was going to point that out too but experimentation shows that in
    practice they return -1. This "feels right" so I suspect it will not
    change in future and I suspect perlfunc will catch up sooner or later.

    Of course fileno() on a tied handle could return anything or even die.
    Brian McCauley, Jan 12, 2005
    #9
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Georgy Pruss
    Replies:
    15
    Views:
    712
    Tim Roberts
    Dec 1, 2003
  2. Tim Peters
    Replies:
    1
    Views:
    346
    Duncan Booth
    Dec 1, 2003
  3. Sean Berry

    Question about glob.glob <--newbie

    Sean Berry, May 4, 2004, in forum: Python
    Replies:
    3
    Views:
    340
    David M. Cooke
    May 4, 2004
  4. Elbert Lev

    glob.glob unicode bug or feature

    Elbert Lev, Jul 31, 2004, in forum: Python
    Replies:
    5
    Views:
    381
    Neil Hodgson
    Aug 2, 2004
  5. Hitesh

    glob.glob output

    Hitesh, Mar 12, 2007, in forum: Python
    Replies:
    6
    Views:
    384
    Hitesh
    Mar 13, 2007
Loading...

Share This Page