Почему я получаю "Глобальный символ '$ href_array' требует определенного имени пакета" в Perl? - PullRequest
1 голос
/ 20 сентября 2010

Я не могу заставить эти массивы работать. Я получаю ошибки по следующим направлениям:

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

}

ИСПРАВЛЕНО:

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

Ответы [ 4 ]

2 голосов
/ 20 сентября 2010

Это означает, что вы используете необъявленную переменную $href_array.Вам нужно переписать эту строку:

while( $href_array ){

примерно так:

foreach my $element (@href_array) {

... хотя в этом коде требуется немного больше контекста, чтобы понять, что это такоеделать - например, вы открываете соединение с базой данных в методе scrape ($dbh = ...), но никогда не используете его.

2 голосов
/ 20 сентября 2010

Ваш код, вероятно, не будет работать так, как вы думаете. Взять, к примеру, этот блок:

}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 получают большую пользу, потому что она предупреждает их именно об этой проблеме!

0 голосов
/ 21 сентября 2010

Во всех этих ответах никто не потрудится сказать вам, что прагма строгая обеспечивает применение некоторых более строгих методов кодирования в Perl.Смотрите его документы для деталей.Мы полностью объясняем это в Learning Perl :)

Когда вы получаете предупреждение, которое вы не понимаете, вы можете получить больше информации с помощью диагностика .Вот пример:

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 "::").
0 голосов
/ 20 сентября 2010

Ваш код включает while($href_array), но вы не объявляете переменную с именем $href_array.

Возможно, вы имели в виду @href_array (это не одна и та же переменная), хотя вы, кажется, не изменяете этот массив внутри цикла.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...