2012-10-24 12 views
9

Ich versuche den Variablenbereich zu verstehen und Variablen in Perl richtig zu deklarieren, und ich habe es schwer.Wie deklariert man globale Variablen in Perl richtig?

Der folgende Code liest grundsätzlich eine Excel-Datei ein, analysiert sie und spuckt sie in eine neue Excel-Datei aus.

Ich versuche jedoch, einen der Header zu lesen, und wenn der Header mit meiner Zeichenfolge übereinstimmt, möchte ich diese Spalte Nummer aufzeichnen und später im Code verwenden.

Ich bekomme eine "Verwendung von nicht initialisierten Wert $ site_name_col im Druck bei ./parser.pl Zeile 38."

Zeile 38 ist "print $ site_name_col;"

Ich weiß, dass diese print-Anweisung außerhalb der {} ist, wo die Variable anfänglich initialisiert wurde, aber am Anfang des Codes als globale Variable deklariert wurde. Was also gibt es?

#!/usr/bin/perl -w 

use strict; 
use warnings; 
use vars qw($site_name_col); 
use Spreadsheet::WriteExcel; 
use Spreadsheet::ParseExcel; 

my ($fname1) = @ARGV; 

my $parser = Spreadsheet::ParseExcel->new(); 
my $workbook = $parser->parse($fname1); 

my $new_workbook = Spreadsheet::WriteExcel->new('formated_list.xls', $fname1); 

if (!defined $workbook) { 

    die $parser->error(), ".\n"; 
} 

for my $worksheet ($workbook->worksheets()) { 

    my ($wsheet_name) = $worksheet->get_name(); 
    my $new_worksheet = $new_workbook->add_worksheet($wsheet_name); 

    my ($row_min, $row_max) = $worksheet->row_range(); 
    my ($col_min, $col_max) = $worksheet->col_range(); 

    for my $row ($row_min .. $row_max) { 

     for my $col ($col_min .. $col_max) { 

      my $cell = $worksheet->get_cell($row, $col); 
      next unless $cell; 

      print "Row, Col = ($row, $col)\n"; 

      if ($cell->value() =~ /Site Name/) { 

       $site_name_col = $col; 
      } 
      print $site_name_col; 

      $new_worksheet->write($row, $col, $cell->value()); 
     } 
    } 
} 

$new_workbook->close(); 
+2

Warum hast du 'my' nicht benutzt ?! – ikegami

Antwort

5

use vars qw() ist nicht mehr empfohlen. Um eine globale Variable zu deklarieren, verwenden Sie our $my_var Ihr Problem kann von der Bedingung $cell->value() =~ /Site Name/ stammen. Es ist wahrscheinlich nie erfüllt, so dass Ihre Variable nie einen Wert erhält.

0

Sie müssen in diesem Fall keine globale Variable deklarieren, lokale Variable ist ausreichend. Siehe Beispiel unten.

if ($cell->value() =~ /Site Name/) { 

    my $site_name_col = $col; 
    print $site_name_col; 
} 

ODER

my $site_name_col = ''; # default value 
if ($cell->value() =~ /Site Name/) { 

    $site_name_col = $col; 
} 
print $site_name_col; 
+1

Sie beantworten keine Frage, warum? – Alex

1

Nur um zu klären, was andere schon gesagt haben, eine Variable an der Spitze einer Datei erklärt mit my ist zugänglich und nutzbar durch Ihre gesamte Datei. In diesem Fall gibt es keinen Grund für eine globale Variable.

Wann möchten Sie global?

  • Sie möchten, dass eine Variable mit einem anderen Code außerhalb Ihrer Datei zugänglich ist. Ein Modul kann beispielsweise eine globale Variable bereitstellen, auf die Dateien zugreifen können, die das Modul aufrufen.
  • Sie haben mehrere Pakete in einer Datei. In diesem Fall benötigen Sie eine globale Variable für etwas, auf das beide Pakete zugreifen. Es wäre jedoch eher ungewöhnlich, dies zu tun.
  • Es ist ziemlich klar, dass Sie keine dieser Sachen tun, also sollten Sie einfach mit my bleiben. Wenn Sie eine globale Deklaration vornehmen möchten, ist der korrekte Weg dazu our. Dieser Befehl enthält einige wichtige Feinheiten, die in der verknüpften Dokumentation erläutert werden.

    3

    i erkennen diesen Beitrag ein wenig alt, aber ... für diejenigen, die noch später auf dieser Seite Jahre kommen (wie ich):

    Ich stelle mir diese Arbeitsblätter zeichnen Sie nicht erstellt wurden, wurden Lesen in durch Sie. Sie können also Gehäuseprobleme feststellen, und Regexes sind natürlich Groß- und Kleinschreibung. Groß- oder Kleinschreibung der Daten bei der Prüfung: if (lc($cell->value()) =~ /site name/) ...

    our verwenden! Es gibt viele Gründe für einen globalen.site_name scheint etwas, das alle Dateien sein müssen möglicherweise ...

    Jarett

    edit:

    dies funktioniert viel besser:

    if ($cell->value()) =~ /site name/i) { print $col; }

    keine Notwendigkeit, außerhalb der drucken, wenn Aussage überhaupt ... spart Drucken nichts viele ... viele Male ....