2010-09-15 7 views
5

Pour une raison quelconque, les handles de fichiers ne peuvent pas fonctionner avec la méthode log_file d'Expect.pm. J'ai d'abord obtenu de l'aide sur How can I pass a filehandle to Perl Expect's log_file function?, où il a été suggéré que j'utilise un handle de fichier IO :: Handle pour passer à la méthode. Cela semble être une question différente, alors j'ai pensé que je commencerais une nouvelle question.Pourquoi mon handle de fichier Perl béni ne renvoie-t-il pas true avec `can ('print)' '?

C'est la partie incriminée de 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 
} 

Ainsi donc, j'ai essayé cet exemple de 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"; 
} 

Quand je lance cela, je reçois deux (à mon avis) des objets contradictoires. Un fichier avec une seule ligne qui dit «Bonjour, monde», et la sortie de «Non». À mon avis, la ligne $fh->can devrait retourner vrai. Est-ce que je me trompe ici?

+2

'use strict; j'utilise des avertissements; ' – Ether

+0

Je n'ai pas de réponse à propos de la raison pour laquelle cela agit bizarrement, mais je soupçonne qu'une partie de cela vient de IO :: Handle n'étant pas une classe normale. Une partie de cela est à l'intérieur de la source Perl au lieu de vivre comme un module normal. Il pourrait mériter un rapport de bug (utilisez perlbug) :) –

Répondre

5

Odd, il semble que vous ayez besoin de créer un objet réel IO::File pour que la méthode can fonctionne. Essayez

use IO::File; 

my $fh = IO::File->new("file.out", ">>") 
    or die "Couldn't open file: $!"; 
+0

Utilisé IO :: Fichier. Merci encore pour votre aide. –

2

IO::Handle ne surcharge pas la fonction open(), de sorte que vous n'obtenez en fait un objet IO::Handle dans $fh. Je ne sais pas pourquoi la ligne $fh->print("Hello, world") fonctionne (probablement parce que vous appelez la fonction print(), et quand vous faites des choses comme $foo->function c'est équivalent à function $foo, donc vous imprimez essentiellement à la poignée de fichier comme vous vous y attendez normalement).

Si vous changez votre code à quelque chose comme:

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"; 
} 

... alors votre code fera comme prévu. Au moins, ça fait pour moi!

+0

Pourquoi utilisez-vous 'open' +' fdopen' au lieu d'utiliser simplement 'IO :: File'? – cjm

+0

Parce que je ne connaissais pas 'IO :: File' jusqu'à ce que j'aie vu la réponse de Chas. J'ai eu 'IO :: Handle' sur le cerveau parce que c'est ce que je pensais que l'OP voulait utiliser. – CanSpice

+0

Je ne connaissais pas non plus IO :: File jusqu'à ce que je l'ai cherché tout de suite. Merci encore pour votre aide! Toujours une expérience d'apprentissage. –