2010-12-13 50 views
1

Tout d'abord, j'ai recherché sur les forums et n'ai pas trouvé exactement mon problème. Je cours Ubuntu avec Perl 5.10 installé.Impossible d'utiliser une valeur indéfinie comme référence de filehandle

Je reçois l'erreur suivante après l'exécution de mon script:

"Can't use an undefined value as filehandle reference at scraper.pl line 17" 

Voici mon script ....

#!/usr/bin/perl -W 
use strict; 
use warnings; 

use WWW::Curl::Easy; 


my $curl = WWW::Curl::Easy->new; 

$curl->setopt(CURLOPT_HEADER, 1); 
$curl->setopt(CURLOPT_URL, 'http://something.com'); 


my $response_body; 
$curl->setopt(CURLOPT_WRITEDATA,\$response_body); 

my $return_code = $curl->perform; 

if ($return_code == 0) 
{ 
    my $response_code = $curl->getinfo(CURLINFO_HTTP_CODE); 
    print ("Success ".$response_code); 
} 
else 
{ 
    # Error Code 
    print ("An error occured: ".$return_code." ".$curl->strerror($return_code)." ".$curl->errbuf."\n"); 
} 

# EOF 

Toute aide serait ici beaucoup apprécié.

Merci,

Ben

+0

où reçoivent-vous l'erreur? – KevinDTimm

+0

@Kevin at scraper.pl ligne 15.;) – bzlm

+0

Désolé ... l'erreur se produit sur la ligne 15 ... my $ return_code = $ curl-> perform; – Bnjmn

Répondre

6

Au lieu de:

my $response_body; 
$curl->setopt(CURLOPT_WRITEDATA,\$response_body); 

faire:

my $response_body = ''; 
open(my $fileb, ">", \$response_body); 
$curl->setopt(CURLOPT_WRITEDATA,$fileb); 

Si vous consultez la documentation de la version de WWW-Curl vous utilisez effectivement, je pense que vous verrez une passe filehandle, pas une référence scalaire.

Vous pouvez également mettre à niveau WWW-Curl.

Notez également que -W n'est généralement pas recommandé; souvent, les modules désactivent les avertissements pour une portée particulière et le commutateur W principal empêche cela. Utilisez -w à la place (ou simplement use warnings; pour votre propre code, ce que vous faites déjà).

+0

Je demande simplement ... pourquoi la communauté a-t-elle choisi de soutenir ce commentaire concernant une solution alors que celle que j'ai désignée comme résolvant le problème reste impopulaire? – Bnjmn

+0

@Bnjmn: à la conjecture, parce que l'autre vous présente une solution de contournement après avoir lu la mauvaise documentation plutôt que d'expliquer que vous l'avez fait? – ysth

+0

Aussi, en utilisant curl pour obtenir quelque chose dans un fichier temporaire est un peu étrange. – ysth

0

Il y a du mauvais code à:

print ("Success ".$response_code); 

Regardez la documentation print: en raison des arguments façon sont analysés lorsque vous utilisez entre parenthèses, le premier argument sera interprété comme un handle de fichier, qui est pas ce que vous avez prévu. Dans votre code, les parenthèses sont inutiles; juste passer une chaîne chaînés, ou mieux, éviter la concaténation et de transmettre une liste de chaînes:

print 'Success ', $response_code; 

Aussi, s'il vous plaît s'il vous plaît comprennent toujours use strict; use warnings; en haut de chaque script que vous écrivez. Vous découvrirez que de nombreuses erreurs sont mises en surbrillance qui peuvent rester cachées pendant un certain temps, et cela permet à tout le monde de gagner du temps lorsque vous rencontrez une erreur avant même d'avoir à vous demander sur Stack Overflow. :)

+0

C'est sur la ligne 20 cependant. – Quentin

+0

Merci pour l'entrée ... une vraie erreur d'amateur :( – Bnjmn

+0

@Bnjmn: pas si cette ligne n'est jamais exécutée:: p – Ether

0
my $response_body; 
$curl->setopt(CURLOPT_WRITEDATA,\$response_body); 

Vous avez déclaré $response_body, mais vous ne lui avez pas affecté de valeur. Je suppose que cela fonctionnerait si vous en faisiez une chaîne.

my $response_body = ""; 

Cela dit, je ne peux pas être sûr car je ne peux pas reproduire l'erreur. Peut-être installer une version plus récente du module aiderait aussi.

+0

Merci pour cette réponse, je sais que perl est particulièrement généreux en termes d'initialisation des variables et donc le correctif que vous avez proposé n'a pas résolu le problème.J'ai également téléchargé la dernière version de la Curl module et fait en sorte que mon interpréteur perl était également assez récent car les messages précédents dans les forums rapportaient des problèmes avec les anciennes versions de perl Mise à jour rapide, quand je change $ response_body à la chaîne vide, l'erreur de l'interpréteur change et dit "Bad filehandle: at scraper.pl line 15 " – Bnjmn

+0

De ce commentaire, n'est-il pas possible que $ curl-> setopt attende un handle de fichier comme deuxième argument plutôt qu'une référence à un scalaire? Si cela ne vous dérange pas, essayez ceci: ouvrir mon $ fh, '>', \ $ response_body ou mourir "$!"; $ curl-> setopt (CURLOPT_WRITEDATA, $ fh); EDIT: Les documents impliquent que cela ne devrait pas importer, cependant. – Hugmeir

+0

@Hugmeir: mais il vérifie les documents les plus récents, pas les docs de la version qu'il a. 4.11 requiert au moins un handle de fichier, pas une référence scalaire. – ysth

2
#!/usr/bin/perl 
use strict; 
use warnings; 

use WWW::Curl::Easy; 
use File::Temp qw/tempfile/; 

my $response_body = tempfile(); 

my $curl = WWW::Curl::Easy->new; 

$curl->setopt(CURLOPT_HEADER, 1); 
$curl->setopt(CURLOPT_URL, 'http://yiddele.com/categoryindex.aspx'); 

#$curl->setopt(CURLOPT_WRITEDATA,\$response_body); 
$curl->setopt(CURLOPT_WRITEDATA, \$response_body); 

my $return_code = $curl->perform; 

if ($return_code == 0) 
{ 
    my $response_code = $curl->getinfo(CURLINFO_HTTP_CODE); 
    print ("Success ".$response_code); 
} 
else 
{ 
    # Error Code 
    print ("An error occured: ".$return_code." ".$curl->strerror($return_code)." ".$curl->errbuf."\n"); 
} 

# EOF 

sortie est:

Success 200
+0

merci d5e5, vous avez remédié au problème. Votre aide est tres apprecie. – Bnjmn

+0

Ce message a été rétrogradé comme solution suggérée, car il représente une solution de contournement quelque peu maladroite, mais il fournit toujours les résultats escomptés. J'ai donc voté pour. – Bnjmn

+0

Merci Bnjmn. Après avoir posté ce qui précède, j'ai vu que ysth avait posté une réponse 4 minutes plus tôt pour laquelle j'avais voté parce qu'elle contenait une explication. Aussi je n'avais pas encore vu le fichier Curl.pm installé avec WWW :: Curl :: Easy, un niveau à partir du dossier Curl contenant Easy.pm. Il contient des exemples utilisant les différentes méthodes, y compris perform. – d5e5

0
 use Data::Printer ; 
     use URI::Encode qw(uri_encode uri_decode); 
     use JSON(); 
     use JSON::Parse ':all' ; 
     use WWW::Curl; 
     use HTTP::Response ; 

     use utf8 ; 
     use Carp ; 
     use Cwd qw (abs_path) ; 
     use Getopt::Long; 

     use WWW::Curl::Easy; 

     my $curl = WWW::Curl::Easy->new; 
     $curl->setopt(WWW::Curl::Easy::CURLOPT_HEADER(),1); 
     $curl->setopt(WWW::Curl::Easy::CURLOPT_URL(), 'https://www.pivotaltracker.com/services/v5/me?fields=%3Adefault'); 
     $curl->setopt(WWW::Curl::Easy::CURLOPT_HTTPHEADER() , ['X-TrackerToken: ' . $TOKEN] ); 
     #$curl->setopt(WWW::Curl::Easy::CURLOPT_POST(), 1); 

     # A filehandle, reference to a scalar or reference to a typeglob can be used here. 
     my $response_body; 
     $curl->setopt(WWW::Curl::Easy::CURLOPT_WRITEDATA(),\$response_body); 

     # Starts the actual request 
     my $ret = $curl->perform; 


     if ($ret == 0) { 

       print("Transfer went ok\n"); 
       my $response_code = $curl->getinfo(CURLINFO_HTTP_CODE); 
       # judge result and next action based on $response_code 

       $response_body = HTTP::Response->parse($response_body); 
       print("Received response: $response_body\n"); 
       p($response_body); 
       my $json_data = $response_body->content ; 

       $json_data = JSON->new->utf8->decode($json_data); 
       p($json_data); 

     } else { 
      # Error code, type of error, error message 
       print("An error happened: $ret ".$curl->strerror($ret)." ".$curl->errbuf."\n"); 
     } 

     # my $cmd='curl -X GET -H "X-TrackerToken: ' . "$TOKEN" . '" "https://www.pivotaltracker.com/services/v5/me?fields=%3Adefault"' ; 
     # my $json_str = `$cmd`; 
     # p($json_str); 
     # my $json_data = JSON->new->utf8->decode($json_str); 
     # p($json_data);