views:

95

answers:

3

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>;
A: 

Not sure if you can do this one, the usual trick of wrapping it in {} gets fouled up by the method call invocation. This might work if you don't have a get_handle sub defined in your package:

my $input = < {get_handle $object} >;

a bit longer is:

my $input = readline $object->get_handle;
Eric Strom
I'd prefer not to use indirect object syntax. It's fragile. I'd have to commit to never allowing my code to come anywhere near a `get_handle` subroutine.
Ryan Thompson
@Ryan: If you're not concerned about this problem from a purely academic perspective, I'd go with the two statement solution that you provided in the question. Syntactically however, it looks like Eric's solution could work. It would look nice in Perl poetry.
Ether
`readline FILE` is the exact same thing as `<FILE>`, so that would work fine.
Brian Roach
+3  A: 

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.

DougWebb
+7  A: 

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.

hobbs
Yeah, my current solution is `readline`.
Ryan Thompson