tags:

views:

64

answers:

2

For some reason, I can't get filehandles working with Expect.pm's log_file method. I originally got help on How can I pass a filehandle to Perl Expect's log_file function?, where it was suggested that I use an IO::Handle filehandle to pass to the method. This seems to be a different issue, so I thought I'd start a new question.

This is the offending section of Expect.pm:

if (ref($file) ne 'CODE') {
  croak "Given logfile doesn't have a 'print' method"
    if not $fh->can("print");
  $fh->autoflush(1);        # so logfile is up to date
}

So, then, I tried this sample code:

use IO::Handle;
open $fh, ">>", "file.out" or die "Can't open file";
$fh->print("Hello, world");
if ($fh->can("print"))
{
  print "Yes\n";
}
else
{
  print "No\n";
}

When I run this, I get two (to my mind) conflicting items. A file with a single line that says 'Hello, world', and output of 'No'. To my mind, the $fh->can line should return true. Am I wrong here?

+2  A: 

IO::Handle doesn't overload the open() function, so you're not actually getting an IO::Handle object in $fh. I don't know why the $fh->print("Hello, world") line works (probably because you're calling the print() function, and when you do things like $foo->function it's equivalent to function $foo, so you're essentially printing to the filehandle like you'd normally expect).

If you change your code to something like:

use strict;
use IO::Handle;
open my $fh, ">>", "file.out" or die "Can't open file";
my $iofh = new IO::Handle;
$iofh->fdopen( $fh, "w" );
$iofh->print("Hello, world");
if ($iofh->can("print"))
{
  print "Yes\n";
}
else
{
  print "No\n";
}

...then your code will do as you expect. At least, it does for me!

CanSpice
Why are you using `open` + `fdopen` instead of just using `IO::File`?
cjm
Because I didn't know about `IO::File` until I saw Chas' reply. I had `IO::Handle` on the brain because that's what I thought the OP wanted to use.
CanSpice
I also didn't know about IO::File until I looked it up just now. Thanks for your help once again! Always a learning experience.
coding_hero
+5  A: 

Odd, it looks like you need to create a real IO::File object to get the can method to work. Try

use IO::File;

my $fh = IO::File->new("file.out", ">>")
    or die "Couldn't open file: $!";
Chas. Owens
Used IO::File. Thanks once again for your help.
coding_hero