angle operator behavior with filehandles in @_

Discussion in 'Perl Misc' started by John Bullock, Aug 29, 2004.

  1. John Bullock

    John Bullock Guest

    Hello,

    I am puzzled by the behavior of the angle
    operator (<>) when it operates on a filehandle
    that is passed to a subroutine.

    Given filehandle FH, these lines are equivalent:

    my $tst1 = <FH>;
    my $tst1 = readline(FH);

    But if I set up a subroutine, there is an oddity:

    do_something(*FH);
    sub do_something {
    my $tst1;
    $tst = $readline($_[0]); # works
    $tst1 = <$_[0]>; # doesn't work
    $tst1 = < {$_[0]} >; # doesn't work
    }

    Of course, I can get around this by storing the filehandle
    in a scalar that I define in the subroutine. But I want to
    understand why neither of the last two lines here works
    as intended. (They just leave $tst1 undefined, provided
    that it hasn't already been defined.) I've looked to what
    I thought were the salient parts of the camel book, but I
    had no luck. Can you enlighten me or point me to some
    relevant reading?

    Thanks,
    --John
     
    John Bullock, Aug 29, 2004
    #1
    1. Advertising

  2. John Bullock wrote:
    > I am puzzled by the behavior of the angle
    > operator (<>) when it operates on a filehandle
    > that is passed to a subroutine.
    >
    > Given filehandle FH, these lines are equivalent:
    >
    > my $tst1 = <FH>;
    > my $tst1 = readline(FH);
    >
    > But if I set up a subroutine, there is an oddity:
    >
    > do_something(*FH);
    > sub do_something {
    > my $tst1;
    > $tst = $readline($_[0]); # works
    > $tst1 = <$_[0]>; # doesn't work
    > $tst1 = < {$_[0]} >; # doesn't work
    > }
    >
    > Of course, I can get around this by storing the filehandle
    > in a scalar that I define in the subroutine.


    Not sure what you mean by that.

    But you can do:

    use Symbol 'qualify_to_ref';

    do_something(*FH);
    sub do_something {
    my $fh = qualify_to_ref($_[0], caller);
    my $tst1 = <$fh>;
    }

    This use of the Symbol module is mentioned in "perldoc perlsub".

    --
    Gunnar Hjalmarsson
    Email: http://www.gunnar.cc/cgi-bin/contact.pl
     
    Gunnar Hjalmarsson, Aug 29, 2004
    #2
    1. Advertising

  3. John Bullock

    John Bullock Guest


    > > Of course, I can get around this by storing the
    > > filehandle in a scalar that I define in the
    > > subroutine.

    >
    > Not sure what you mean by that.


    Sorry. What I mean is that by assigning the
    filehandle to a scalar, and then using the angle operator
    on that scalar, I can get the angle operator to work as I
    desire. For example, this code uses that procedure to
    store the contents of a file in an array:

    do_something(*FH);
    sub do_something {
    my $tst1 = shift;
    my @tst1 = <$tst1>;
    }

    But if I don't assign the filehandle to a scalar,
    I don't know how to achieve the same result. The
    following code, for example, is no good:

    do_something(*FH);
    sub do_something {
    my @tst1 = $_[0]; # @tst1 gets filehandle rather than file contents
    my @tst1 = < $_[0] >; # @tst1 is undefined
    my @tst1 = < {$_[0]} >; # @tst1 is undefined
    }


    Thank you for letting me know about the Symbol
    module. I'm curious, though, to know why the last lines
    of code in my original post don't work as intended --
    what rules do they violate, and what's the logic behind
    those rules? I checked perldoc perlsub/perldata/Symbol,
    but couldn't find a clarification.

    Thanks again,
    --John


    "Gunnar Hjalmarsson" <> wrote in message news:...
    > John Bullock wrote:
    > > I am puzzled by the behavior of the angle
    > > operator (<>) when it operates on a filehandle
    > > that is passed to a subroutine.
    > >
    > > Given filehandle FH, these lines are equivalent:
    > >
    > > my $tst1 = <FH>;
    > > my $tst1 = readline(FH);
    > >
    > > But if I set up a subroutine, there is an oddity:
    > >
    > > do_something(*FH);
    > > sub do_something {
    > > my $tst1;
    > > $tst = $readline($_[0]); # works
    > > $tst1 = <$_[0]>; # doesn't work
    > > $tst1 = < {$_[0]} >; # doesn't work
    > > }
    > >
    > > Of course, I can get around this by storing the filehandle
    > > in a scalar that I define in the subroutine.

    >
    > Not sure what you mean by that.
    >
    > But you can do:
    >
    > use Symbol 'qualify_to_ref';
    >
    > do_something(*FH);
    > sub do_something {
    > my $fh = qualify_to_ref($_[0], caller);
    > my $tst1 = <$fh>;
    > }
    >
    > This use of the Symbol module is mentioned in "perldoc perlsub".
    >
    > --
    > Gunnar Hjalmarsson
    > Email: http://www.gunnar.cc/cgi-bin/contact.pl
     
    John Bullock, Aug 29, 2004
    #3
  4. John Bullock

    Joe Smith Guest

    John Bullock wrote:

    > $tst = $readline($_[0]); # works
    > $tst1 = <$_[0]>; # doesn't work
    > $tst1 = < {$_[0]} >; # doesn't work
    >
    > Of course, I can get around this by storing the filehandle
    > in a scalar that I define in the subroutine. But I want to
    > understand why neither of the last two lines here works
    > as intended. (They just leave $tst1 undefined, provided
    > that it hasn't already been defined.) I've looked to what
    > I thought were the salient parts of the camel book, but I
    > had no luck. Can you enlighten me or point me to some
    > relevant reading?


    This section from 'perldoc perlop':

    If what the angle brackets contain is a simple scalar variable (e.g.,
    <$foo>), then that variable contains the name of the filehandle to
    input from, or its typeglob, or a reference to the same. For example:

    $fh = \*STDIN;
    $line = <$fh>;

    If what's within the angle brackets is neither a filehandle nor a sim-
    ple scalar variable containing a filehandle name, typeglob, or typeglob
    reference, it is interpreted as a filename pattern to be globbed, and
    either a list of filenames or the next filename in the list is
    returned, depending on context. This distinction is determined on syn-
    tactic grounds alone. That means "<$x>" is always a readline() from an
    indirect handle, but "<$hash{key}>" is always a glob(). That's because
    $x is a simple scalar variable, but $hash{key} is not--it's a hash ele-
    ment.

    -Joe
     
    Joe Smith, Aug 29, 2004
    #4
  5. On 2004-08-29, John Bullock <> wrote:
    >
    > $tst = $readline($_[0]); # works
    > $tst1 = <$_[0]>; # doesn't work
    > $tst1 = < {$_[0]} >; # doesn't work


    The last two lines get parsed as filename globs, not as readlines.
    The angle bracket syntax is ambiguous in this sense, and in this case
    perl doesn't do quite what you meant.

    You've already discovered the two obvious ways around this: either
    call readline() explicitly or assign $_[0] to a simple scalar
    variable. Either way will work.

    --
    Ilmari Karonen
    If replying by e-mail, please replace ".invalid" with ".net" in address.
     
    Ilmari Karonen, Aug 29, 2004
    #5
  6. John Bullock

    Anno Siegel Guest

    Joe Smith <> wrote in comp.lang.perl.misc:
    > John Bullock wrote:


    [...]

    > This section from 'perldoc perlop':
    >
    > If what the angle brackets contain is a simple scalar variable (e.g.,
    > <$foo>), then that variable contains the name of the filehandle to
    > input from, or its typeglob, or a reference to the same. For example:
    >
    > $fh = \*STDIN;
    > $line = <$fh>;
    >
    > If what's within the angle brackets is neither a filehandle nor a sim-
    > ple scalar variable containing a filehandle name, typeglob, or typeglob

    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    > reference, it is interpreted as a filename pattern to be globbed, and

    ^^^^^^^^^
    > either a list of filenames or the next filename in the list is
    > returned, depending on context. This distinction is determined on syn-
    > tactic grounds alone. That means "<$x>" is always a readline() from an
    > indirect handle, but "<$hash{key}>" is always a glob(). That's because
    > $x is a simple scalar variable, but $hash{key} is not--it's a hash ele-
    > ment.


    The hilighted clause makes the sentence ambiguous. I would read it as
    saying that for a thing to be taken as a filehandle it must (a) be
    a simple scalar variable and (b) contain a filehandle name, typeglob,
    or typeglob reference. Only the next sentence ("on syntactic grounds
    alone") makes clear that it means the variable must be a simple variable,
    which then, (to make sense) must contain one of those things.

    I'd suggest changing the second paragraph to:

    If what's within the angle brackets is neither a filehandle
    nor a simple scalar variable, its content (any string value)
    will be interpreted as a filename pattern to be globbed, and
    either a list of filenames or the next filename in the list is
    returned, depending on context. This distinction is determined
    on syntactic grounds alone. ...

    Anno
     
    Anno Siegel, Aug 30, 2004
    #6
    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. Darren Grant

    Angle class - how is my code ?

    Darren Grant, Dec 15, 2003, in forum: C++
    Replies:
    5
    Views:
    531
    Darren Grant
    Dec 16, 2003
  2. bartek
    Replies:
    1
    Views:
    8,020
    Unforgiven
    May 26, 2004
  3. =?Utf-8?B?U3VyYWpQcmFiaHU=?=

    Drawing line at an angle in ASP.nt

    =?Utf-8?B?U3VyYWpQcmFiaHU=?=, Jun 8, 2006, in forum: ASP .Net
    Replies:
    0
    Views:
    428
    =?Utf-8?B?U3VyYWpQcmFiaHU=?=
    Jun 8, 2006
  4. Andrew Dunbar

    Extending the line input (angle) operator

    Andrew Dunbar, Oct 28, 2004, in forum: Perl Misc
    Replies:
    1
    Views:
    97
    Peter Wyzl
    Oct 28, 2004
  5. Ed Mancebo

    angle operator, backticks, and redirection

    Ed Mancebo, Jan 12, 2005, in forum: Perl Misc
    Replies:
    6
    Views:
    153
    Tad McClellan
    Jan 13, 2005
Loading...

Share This Page