Question

I have an object with a method that returns a filehandle, and I want to read from that handle. The following doesn't work, because the right angle bracket of the method call is interpreted as the closing angle bracket of the input reader:

my $input = <$object->get_handle()>;

That gets parsed as:

my $input = ( < $object- > ) get_handle() >;

which is obviously a syntax error. Is there any way I can perform a method call within an angle operator, or do I need to break it into two steps like this?

my $handle = $object->get_handle();
my $input = <$handle>;
Was it helpful?

Solution

You have to break it up; the <> operator expects a typeglob like <STDIN>, a simple scalar variable containing a reference to a filehandle or typeglob like <$fh>, or an argument for the glob() function like <*.c>. In your example, you're actually calling glob('$object-').

<> is actually interpreted as a call to readline(), so if you really want to you could say my $input = readline( $object->get_handle() ); I'm not sure that's cleaner though, especially if you're going to read from the handle more than once.

See http://perldoc.perl.org/perlop.html#I%2fO-Operators for details.

OTHER TIPS

You could consider spelling <...> as readline(...) instead, which avoids the problem by using a nice regular syntax instead of a special case. Or you can just assign it to a scalar. Your choice.

my $input = readline($object->get_handle());

or

use IO::Handle;

my $input = $object->get_handle()->getline();

You won't be able to use the <...> operator here to read a file handle, because anything more complex than <bareword> or <$scalar> is interpreted as a glob(...) call, so none of the usual disambiguation tricks will work here. The <HANDLE> operator is syntactic sugar for readline HANDLE, so you could write it this way:

my $input = readline $object->get_handle;

However, if you will be doing this in a loop, it will be far more efficient to cache the handle in a scalar. Then the <...> operator will work as you expected:

my $handle = $object->get_handle;
while (my $input = <$handle>) {
    ...
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top