为什么 URI 对象无法定位方法"scheme"?



我正试图使用以下源代码创建一个异步http请求客户端:

#!perl
use URI;
use DDP;
use threads;
use Thread::Queue;
use LWP::UserAgent;
use constant NUM_WORKERS => 25;
my $req_q = Thread::Queue->new();
my $res_q = Thread::Queue->new();
my @urls = ( "http://google.com", "http://web.de" );
my @workers;
for ( 1 .. NUM_WORKERS ) {
    push @workers, async {
        my $ua = LWP::UserAgent->new();
        while ( my $req = $req_q->dequeue() ) {
            $res_q->enqueue( $ua->request($req) );
        }
    };
}
for my $url (@urls) {
    $req_q->enqueue( HTTP::Request->new( GET => $url ) );
}
$req_q->enqueue(undef) for @workers;
for ( 1 .. @urls ) {
    my $res = $res_q->dequeue();
    p $res;
}
$_->join() for @workers;

不幸的是,我收到错误:

400 Can't locate object method "scheme" via package "URI::http"

这应该是URI模块的问题,但如果我在其他脚本中使用URI包,它可以正常工作。

我尝试将URI升级到URI-1.64(从1.60升级),在fedora(x86_64 GNU/Linux)perl5.16和ubuntu(i686 athlon i386 GNU/Linu克斯)perl5.14上测试。

例如

 $perl -MURI -E'say $INC{"URI.pm"}; say URI->VERSION; say URI->new("http://www.google.com/")->scheme'
 $/home/xxxxx/perl5/lib/perl5/URI.pm
 $1.64
 $http

知道解决故障的最佳方法是什么吗?

原始代码使用Thread::Queue::Any而不是Thread::Queue,因为它能更好地处理对象。然而,原始代码中有两个错误(现已修复)。

use Thread::Queue::Any 1.03 qw( );
...
my $req_q = Thread::Queue->new();
my $res_q = Thread::Queue->new();

应该是

use Thread::Queue::Any 1.03;  # Must call import.
...
my $req_q = Thread::Queue::Any->new();
my $res_q = Thread::Queue::Any->new();

线程::队列::Any在import中工作,但不应该在那里,所以我不调用import的习惯做法适得其反。

这些微小的更改将允许代码工作。


如果想继续使用Thread::Queue,那么在调用use threads;之前,似乎必须加载共享对象的模块(我认为这会节省内存,所以无论如何都是好主意。)URI动态加载URI::http,因此需要添加

use URI::http;

BEGIN { URI->new('', 'http') }

use threads; 之前

这会让你通过那个问题(并进入另一个问题)。

最新更新