angle operator behavior with filehandles in @_

J

John Bullock

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
 
G

Gunnar Hjalmarsson

John said:
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".
 
J

John Bullock

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 said:
John said:
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".
 
J

Joe Smith

John said:
$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
 
I

Ilmari Karonen

$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.
 
A

Anno Siegel

Joe Smith said:
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
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,764
Messages
2,569,566
Members
45,041
Latest member
RomeoFarnh

Latest Threads

Top