如何在Perl中正确声明全局变量?

时间:2012-10-24 05:17:09

标签: perl

我正在尝试理解变量范围并在Perl中正确声明变量,而且我很难。

下面的代码基本上读取一个excel文件,解析它,并将其吐出到一个新的excel文件。

但是,我正在尝试读取其中一个标题,如果标题与我的字符串匹配,我想记录该列号,稍后在代码中使用它。

我在./parser.pl第38行打印出“使用未初始化的值$ site_name_col。”

第38行是“print $ site_name_col;”

我意识到这个print语句在最初初始化变量的{}之外,但它在代码的开头被声明为一个全局变量,所以给出了什么?

#!/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();

4 个答案:

答案 0 :(得分:5)

use vars qw()不再推荐。要声明全局变量,请使用our $my_var 您的问题可能来自条件$cell->value() =~ /Site Name/。它可能永远不会被满足,所以你的变量永远不会得到一个值。

答案 1 :(得分:3)

我认为这篇文章有点陈旧,但是...对于那些年后仍然会出现在这个页面的人(像我一样):

我想你正在阅读的这些excel工作表可能不是由你创建的。因此,您可能会遇到套管问题,当然,正则表达式区分大小写。检查期间数据的大写或小写:if (lc($cell->value()) =~ /site name/) ...

使用our有很多理由可以拥有全局。 site_name似乎是所有文件可能需要的东西......

Jarett

编辑:

这会更好:

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

根本不需要在if语句之外打印...节省打印很多次......很多次....

答案 2 :(得分:1)

为了澄清其他人已经说过的内容,在my文件顶部声明的变量可供整个文件访问和使用。在这种情况下,没有理由建立全局变量。

你想什么时候全球化?

  • 您希望变量可以通过文件之外的另一段代码访问。例如,模块可能提供可由调用模块的文件访问的全局变量。
  • 您在一个文件中有多个包。在这种情况下,您需要一个全局变量来处理两个包访问的内容。然而,这样做是相当不寻常的。

很明显,你没有做过这两件事,所以你应该坚持使用my。如果您确实要声明全局,那么正确的方法是使用our。该命令有一些重要的细微之处,在链接文档中有解释。

答案 3 :(得分:0)

在这种情况下你不需要声明全局变量,局部变量就足够了。见下面的例子。

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

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

OR

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

    $site_name_col = $col;
}
print $site_name_col;