drewrockshard
drewrockshard

Reputation: 2071

Perl - Using a Variable that is inside an if statement

I've been putting together a Perl script that defines a variable, and then via an if statement will assign a new value to the variable.

I want to use the last assigned value from the if statement and reference it somewhere else outside the if altogether.

It appears that when referencing it that it uses the original value.

Here's the code:

## 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--

The output I get is the name of the file that was originally opened, not the value after modification by the substitutions in the if statements.

This is error correction: it checks the filename that it gets from the file, and if it matches something, it corrects it, and in the end, I have an old variable $FILENAME with a new value that I want to use outside the if.

Upvotes: 0

Views: 2990

Answers (2)

GWP
GWP

Reputation: 131

Declare variables outside of (before) the conditional unless they will only be used inside of that conditional block {}.

Also, use strict; use warnings;

Upvotes: 0

Borodin
Borodin

Reputation: 126722

I struggled to understand the code in your question, mainly because of all the upper case strings; both identifiers and comments

Local identifiers in most languages, including Perl, are usually written using lower-case letters, digits, and the underscore _. Capital letters are reserved for global variables, and in Perl's case that is mostly package (class) names

Identifiers of important variables use capital letters so that they stand out from the rest; but in your example most identifiers are all-capitals. It is diffifult to understand the structure of your code if every identifier says it's very important

I have looked carefully at the code you show, and have done my best to reorganise and simplify it so that it is more legible and does what I think you intended. I have added declarations for all of the variables that are not declared within your code sample, and have added what I think are the correct closing braces } to balance the syntax so that it will compile

As others have noted, the second conditional clause that tests for underscore followed by two spaces will never be executed, because the preceding test for underscore followed by one space will already have caught that case. It is also pointless to use a separate pattern match to determine whether a substitution s/// will succeed, as the substitution alone does nothing and returns a false value if there was no match

The intention is to help you to write Perl code that you can understand, as well as others who you may ask for help (like Stack Overflow) or may be given the job of maintaining your software.

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

    }
  }
}

Upvotes: 1

Related Questions