我似乎无法让这些数组工作。我在以下几行中遇到错误:
Global symbol '$href_array' requires specific package name
这是什么意思?这是我的代码的一部分:
sub scrape {
my ( $self, $DBhost, $DBuser, $DBpass, $DBname ) = @_;
my ($dbh, $query, $result, $array);
my $DNS = "dbi:mysql:$DBname:$DBhost:3306";
$dbh = DBI->connect($DNS, $DBuser, $DBpass ) or die $DBI::errstr;
if( defined( $self->{_process_image} ) && ( -e 'href_w_' . $self->{_process_image} . ".txt" ) ) {
open ERROR_W, "error_w_" . $self->{_process_image} . ".txt";
open M_HREF_W, "m_href_w_" . $self->{_process_image} . ".txt";
open HREF_W, "href_w_" . $self->{_process_image} . ".txt";
my @m_error_array = ( split( '|||', <ERROR_W> ) );
my @m_href_array = ( split( '|||', <M_HREF_W> ) );
my @href_array = ( split( '|||', <HREF_W> ) );
close ( ERROR_W );
close ( M_HREF_W );
close ( HREF_W );
}else{
my @m_error_array;
my @m_href_array;
my @href_array = ( $self->{_url} );
}
my $z = 0;
while( $href_array ){
if( defined( $self->{_x_more} ) && $z == $self->{_x_more} ) {
break;
}
if( defined( $self->{_process_image} ) ) {
$self->write( 'm_href_w', @m_href_array );
$self->write( 'href_w', @href_array );
$self->write( 'error_w', @m_error_array );
}
$self->{_link_count} = scalar @m_href_array;
}
}
FIXED:
#!/usr/bin/perl
use strict;
use URI;
use File::Basename;
use DBI;
package Crawler;
sub new {
my $class = shift;
my $self = {
_url => shift,
_max_link => 0,
_local => 1
};
bless $self, $class;
return $self;
}
sub process_image {
my ($self, $process_image) = @_;
$self->{_process_image} = $process_image;
}
sub local {
my ($self, $local) = @_;
$self->{_local} = $local;
}
sub max_link {
my ($self, $max_link) = @_;
$self->{_max_link} = $max_link;
}
sub x_more {
my ($self, $x_more) = @_;
$self->{_x_more} = $x_more;
}
sub resolve_href {
my ($base, $href) = @_;
my $uri = URI->new($href);
return $uri->rel($base);
}
sub write {
my ( $self, $ref, $data ) = @_;
open FILE, '>>' . $ref . '_' . $self->{_process_image} . '.txt';
print FILE join( '|||', $data );
close( FILE );
}
sub scrape {
my @m_error_array;
my @m_href_array;
my @href_array;
my ( $self, $DBhost, $DBuser, $DBpass, $DBname ) = @_;
my ($dbh, $query, $result, $array);
my $DNS = "dbi:mysql:$DBname:$DBhost:3306";
$dbh = DBI->connect($DNS, $DBuser, $DBpass ) or die $DBI::errstr;
if( defined( $self->{_process_image} ) && ( -e 'href_w_' . $self->{_process_image} . ".txt" ) ) {
open ERROR_W, "error_w_" . $self->{_process_image} . ".txt";
open M_HREF_W, "m_href_w_" . $self->{_process_image} . ".txt";
open HREF_W, "href_w_" . $self->{_process_image} . ".txt";
my @m_error_array = ( split( '|||', <ERROR_W> ) );
my @m_href_array = ( split( '|||', <M_HREF_W> ) );
my @href_array = ( split( '|||', <HREF_W> ) );
close ( ERROR_W );
close ( M_HREF_W );
close ( HREF_W );
}else{
@href_array = ( $self->{_url} );
}
my $z = 0;
while( @href_array ){
if( defined( $self->{_x_more} ) && $z == $self->{_x_more} ) {
break;
}
if( defined( $self->{_process_image} ) ) {
$self->write( 'm_href_w', @m_href_array );
$self->write( 'href_w', @href_array );
$self->write( 'error_w', @m_error_array );
}
$self->{_link_count} = scalar @m_href_array;
}
}
1;
#$query = "SELECT * FROM `actwebdesigns.co.uk` ORDER BY ID DESC";
#$result = $dbh->prepare($query);
#$result->execute();
#while( $array = $result->fetchrow_hashref() ) {
# print $array->{'URL'} . "\n";
#}
答案 0 :(得分:2)
这意味着您正在使用未声明的变量$href_array
。你需要重写这一行:
while( $href_array ){
类似于:
foreach my $element (@href_array) {
...虽然此代码中需要更多上下文才能理解它正在做什么 - 例如,您使用scrape
方法($dbh = ...
)打开数据库连接,但从不使用它。
答案 1 :(得分:2)
您的代码可能无法以您认为的方式运行。以这个块为例:
}else{
my @m_error_array;
my @m_href_array;
my @href_array = ( $self->{_url} );
}
这样做是声明三个数组。这一切都很好,但是因为你使用了my
,当它们在else{}
块结束时超出范围时,它们会“消失”。您可能希望在if...else
块之前在顶部声明它们,并从if...else
部分的两个块中删除重复的声明。
然后,您可能正在尝试迭代@href_array
列表。您需要将while()
更改为:
foreach my $href_array ( @href_array ) {
...
}
所有这一切,赞成将use strict
放入您的代码中(它必须在那里,否则您将不会收到您所做的警告)。对于Perl新手的程序员来说,这是一件非常重要的事情,因为它会警告他们这个问题!
答案 2 :(得分:0)
您的代码包含while($href_array)
,但您没有声明名为$href_array
的变量。
你可能意味着@href_array
(这些变量不是同一个变量),尽管你似乎没有在循环中修改这个数组。
答案 3 :(得分:0)
在所有这些答案中,没有人会告诉你strict pragma在Perl中强制执行一些更严格的编码实践。有关详细信息,请参阅其文档。我们在 Learning Perl 中完全解释了它:)
当您收到不明白的警告时,可以使用diagnostics获取更多信息。这是一个例子:
use strict;
use diagnostics;
while( $href ) { 1 };
以下是扩展错误消息:
Execution of /Users/brian/Desktop/t aborted due to compilation errors (#1)
(F) You've said "use strict" or "use strict vars", which indicates
that all variables must either be lexically scoped (using "my" or "state"),
declared beforehand using "our", or explicitly qualified to say
which package the global variable is in (using "::").