开发者

Why do I get "Global symbol '$href_array' requires specific package name" in Perl?

I can't seem to get these arrays to work. I'm getting errors along the following lines:

Global symbol '$href_array' requires specific package name

What does this mean? Here's part of my code:

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


Your code probably won't work the way you think it will. Take, for example, this block:

}else{
    my @m_error_array;
    my @m_href_array;
    my @href_array = ( $self->{_url} );
}

What this does is declare three arrays. That's all fine and good, but because you've used my, they "disappear" when they go out of scope at the end of the else{} block. You probably want to declare them up at the top, before your if...else block and remove the duplicated declarations from both blocks in the if...else section.

Then, you're probably trying to iterate over the @href_array list. You'll want to change your while() to something like:

foreach my $href_array ( @href_array ) {
    ...
}

All that said, kudos for putting use strict in your code (it must be there, or else you wouldn't have received the warning you did). That's an important thing that programmers new to Perl greatly benefit from, because it warns them about exactly this problem!


It means you are using an undeclared variable $href_array. You need to rewrite this line:

while( $href_array ){

to something like:

foreach my $element (@href_array) {

...although a bit more context is needed in this code to be able to understand what it is doing -- for example, you open a database connection in the scrape method ($dbh = ...), but never use it.


Your code includes while($href_array) but you don't declare a variable called $href_array.

You may have meant @href_array (these are not the same variable), although you don't seem to modify this array inside the loop.


In all these answers no one bothers to tell you that the strict pragma enforces some more stringent coding practices in Perl. See its docs for the details. We explain it fully in Learning Perl too :)

When you get a warning you don't understand, you can get more information with the diagnostics. Here's an example:

use strict;
use diagnostics;

while( $href ) { 1 };

Here's the extended error message:

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 "::").
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜