【问题标题】:Perl - Using a Variable that is inside an if statementPerl - 使用 if 语句中的变量
【发布时间】:2014-07-19 09:09:48
【问题描述】:

我一直在编写一个定义变量的 Perl 脚本,然后通过 if 语句为变量分配一个新值。

我想使用 if 语句中的最后一个赋值,并在 if 之外的其他地方完全引用它。

似乎在引用它时它使用了原始值。

代码如下:

## VARIABLES
my $FILENAME = $input[0];

open my $info, $DATAFILE or die "can't open <$DATAFILE> for reading $!";

{
  while (my $line = <$info>) {

    chomp $line;
    my @input = split(':', $line);
    chomp(@input);

    $FILENAME     = $input[0];
    $PERMIT       = $input[1];
    $FILESIZE     = -s "$TIFF_DL_LOCATION/$PERMIT\_$FILENAME";
    $SHORT_PERMIT = substr($PERMIT, 0, 2);

    ### DEBUG ONLY ###
    print "$FILENAME / $PERMIT / $FTPBASE/$SHORT_PERMIT/$PERMIT/$FILENAME\n";

    my $ftp = Net::FTP::Throttle->new(
      "example.com",
      MegabitsPerSecond => $THROTTLELVL,
      Debug             => $DEBUGLVL
    ) or die "Cannot connect: $@";

    $ftp->login("anonymous", 'anonymous') or die "Cannot login ", $ftp->message;
    $ftp->binary or die "Unable to set binary mode ", $ftp->message;

    if ($PROGRESSBAR eq 1) {

      print "\n[$./$LINE_COUNT] Downloading $FILENAME\n";
      my $REMOTE_FILESIZE = $ftp->size("/PATH/TO/DATA/$SHORT_PERMIT/$PERMIT/$FILENAME");

      if (!defined($REMOTE_FILESIZE)) {

        print "=> FILE DOES NOT APPEAR TO EXIST ON FTP SERVER\n";

        if ($FILENAME =~ m/_\s/) {

          print "=> ATTEMPTING TO FIX NOW\n";
          $FILENAME =~ s/_\s/, /g;
          $REMOTE_FILESIZE = $ftp->size("/PATH/TO/DATA/$SHORT_PERMIT/$PERMIT/$FILENAME");

          if (!defined($REMOTE_FILESIZE)) {
            print "=> FAILED!\n";
          }
        }
        elsif ($FILENAME =~ m/_\s\s/) {

          print "=> ATTEMPTING TO FIX NOW\n";
          $FILENAME =~ s/_\s\s/, /g;
          $REMOTE_FILESIZE = $ftp->size("/PATH/TO/DATA/$SHORT_PERMIT/$PERMIT/$FILENAME");

          if (!defined($REMOTE_FILESIZE)) {
            print "$FILENAME\n";
            print "=> FAILED!\n";
          }
        }
        else {
          print "=> ALL ATTEMPTS TO RESOLVE THE ISSUE HAVE FAILED.\n";
          next;
        }
      }

      $REMOTE_FILESIZE = $ftp->size("/PATH/TO/DATA/$SHORT_PERMIT/$PERMIT/$FILENAME");
      print "FILENAME: $FILENAME\n";

      --- SNIP SNIP - MORE DATA, NOT RELEVANT--

我得到的输出是最初打开的文件的名称,而不是 if 语句中的替换修改后的值。

这是错误更正:它检查从文件中获取的文件名,如果匹配,它会更正它,最后,我有一个旧变量 $FILENAME 和一个我想要的新值在if之外使用。

【问题讨论】:

  • 也许我误解了这个问题,但我没有看到任何 $FILENAME 被重新分配的代码。如果您希望更改 $FILENAME 的值,那么我希望在原始分配之外的代码中的某处看到“$FILENAME = ...”。相反,我只看到 $FILENAME =~ 这是一个搜索绑定运算符,完全不同。
  • 您可能有错字。把'使用严格;'和“使用警告;”在脚本的顶部。它会警告您在不同范围内重新定义的变量。
  • @drewrockshard 您是否尝试在 ' $FILENAME =~ s/_\s/, /g;' 之前和之后打印 $FILENAME在 if/elsif 块中检查是否确实存在替换或 if/elsif 块谓词是否满足。
  • 我同意 keety。 '$FILENAME =~ m/_\s\s/' 永远不会被匹配,因为它总是首先匹配 '$FILENAME =~ m/_\s/'。
  • @drewrockshard:我已经编辑了您的问题,使其更具可读性。请检查以确保它符合您的意图

标签: perl variables if-statement scope


【解决方案1】:

我很难理解您问题中的代码,主要是因为所有的大写字符串;标识符和 cmets

大多数语言(包括 Perl)中的本地标识符通常使用小写字母、数字和下划线 _ 编写。大写字母保留给 全局 变量,在 Perl 的情况下,主要是包(类)名称

重要变量的标识符使用大写字母,以便它们脱颖而出;但在您的示例中,大多数标识符都是大写的。如果每个标识符都说它非常重要,那么很难理解代码的结构

我仔细查看了您展示的代码,并尽我所能重新组织和简化它,使其更清晰易读,并符合我认为您的意图。我为您的代码示例中未声明的所有变量添加了声明,并添加了我认为正确的右大括号 } 以平衡语法以便编译

正如其他人所指出的,测试下划线后跟 两个 空格的第二个条件子句将永远不会执行,因为前面的下划线后跟 一个 空格测试将已经抓到那个案子了。使用单独的模式匹配来确定替换 s/// 是否会成功也是没有意义的,因为替换本身什么也不做,如果没有匹配则返回 false

目的是帮助您编写 可以理解的 Perl 代码,以及您可能需要帮助的其他人(例如 Stack Overflow)或可能负责维护您的软件的人.

use strict;
use warnings;

my ($progressbar, $line_count);
my ($datafile, $ftpbase, $short, $tiff_dl_location);
my ($throttlelvl, $debuglvl);
my @input;

## Variables
my $filename = $input[0];

open my $info, $datafile or die "can't open <$datafile> for reading $!";

{
  while (<$info>) {

    chomp;
    my ($filename, $permit) = split /:/;

    my $filesize = -s "$tiff_dl_location/${permit}_${filename}";
    my $short_permit = substr $permit, 0, 2;

    ### DEBUG ONLY ###
    print "$filename / $permit / $ftpbase/$short_permit/$permit/$filename\n";

    my $file_path = "/PATH/TO/DATA/$short_permit/$permit/$filename";

    my $ftp = Net::FTP::Throttle->new(
      "example.com",
      MegabitsPerSecond => $throttlelvl,
      Debug             => $debuglvl
    ) or die "Cannot connect: $@";

    $ftp->login(qw/ anonymous anonymous /) or die "Cannot login: ", $ftp->message;
    $ftp->binary or die "Unable to set binary mode ", $ftp->message;

    if ($progressbar == 1) {

      print "\n[$./$line_count] Downloading $filename\n";
      my $remote_filesize = $ftp->size($file_path);

      if (not defined $remote_filesize) {

        warn "=> File does not appear to exist on FTP server\n";
        warn "=> Attempting to fix now\n";

        $filename =~ s/_\s+/, /g;
        $remote_filesize = $ftp->size($file_path);

        if (not defined $remote_filesize) {
          warn "=> ALL ATTEMPTS TO RESOLVE THE ISSUE HAVE FAILED.\n";
          next;
        }
      }

      print "File name: $filename\n";

      # --- snip snip - more data, not relevant ---

    }
  }
}

【讨论】:

    【解决方案2】:

    在条件之外(之前)声明变量,除非它们只会在条件块 {} 内使用。

    另外, 使用严格; 使用警告;

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-04-11
      • 1970-01-01
      • 1970-01-01
      • 2017-03-02
      • 1970-01-01
      • 2017-10-13
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多