variable scope and use strict

Discussion in 'Perl Misc' started by Rocky, Apr 27, 2004.

  1. Rocky

    Rocky Guest

    I am trying to use strict all the time now. I have a problem with the
    following code. When I use strict the value of $highest won't leave the
    foreach construct. I know this is by design but I cannot figure out how
    make that variable available outside the loop. Any advice?

    Also if someone could tell me where to find perldoc regarding "use
    strict;" or scoping in general I would appreciate it.


    #!/usr/bin/perl
    my $number = 1;
    my $dir = "/etc/backup";
    opendir DIR1, $dir;
    my @files = readdir(DIR1);
    closedir DIR1;
    foreach my $filename (@files)
    {
    push(@filenum, $1) if ($filename =~ /^CUX(\d+)\.txt$/);
    #my $highest = (sort { $a <=> $b } @filenum)[-1];
    }
    $highest = (sort { $a <=> $b } @filenum)[-1];
    $final = $highest + $number;
    print "CUX00" . "$final" . ".txt\n";
    Rocky, Apr 27, 2004
    #1
    1. Advertising

  2. Rocky

    Tore Aursand Guest

    On Tue, 27 Apr 2004 12:46:17 +0000, Rocky wrote:
    > I am trying to use strict all the time now.


    But you don't. Your code doesn't use strict at all. It doesn't use
    warnings, either;

    #!/usr/bin/perl
    #
    use strict;
    use warnings;

    > I have a problem with the following code. When I use strict the value
    > of $highest won't leave the foreach construct. I know this is by design
    > but I cannot figure out how make that variable available outside the
    > loop. Any advice?
    >
    > my $dir = "/etc/backup";


    Needless use of double quotes;

    my $dir = '/etc/backup';

    > opendir DIR1, $dir;


    Always check if 'open()' and 'opendir()' succeeds;

    opendir( DIR1, $dir ) or die "$!\n";

    Eventually;

    if ( opendir(DIR1, $dir) ) {
    closedir( DIR1 );
    }
    else {
    # Something bad happened; Error message in $!
    }

    > my @files = readdir(DIR1);
    > closedir DIR1;
    > foreach my $filename (@files) {
    > push(@filenum, $1) if ($filename =~ /^CUX(\d+)\.txt$/); #my
    > $highest = (sort { $a <=> $b } @filenum)[-1];
    > }
    > $highest = (sort { $a <=> $b } @filenum)[-1]; $final = $highest
    > + $number;
    > print "CUX00" . "$final" . ".txt\n";


    You could always make sure that you have the correct set of files when you
    first read them in with 'readdir';

    my @files = grep { /^CUX\d+\.txt$/ } readdir( DIR1 );

    It seems to be that you're trying to find the filename which have the
    highest number. This could be done like this;

    opendir( DIR1, $dir ) or die "$!\n";
    my @files = sort { $a <=> $b } grep { /^CUX\d+\.txt$/ } readdir( DIR1 );
    closedir( DIR1 );

    print 'Highest valued filename: ' . $files[-1] . "\n";

    > Also if someone could tell me where to find perldoc regarding "use
    > strict;" or scoping in general I would appreciate it.


    I guess 'perldoc strict' would get you going.


    --
    Tore Aursand <>
    "War is too serious a matter to entrust to military men." (Georges
    Clemenceau)
    Tore Aursand, Apr 27, 2004
    #2
    1. Advertising

  3. Rocky

    Rocky Guest

    On Tue, 27 Apr 2004 15:00:50 +0200, Tore Aursand wrote:

    > On Tue, 27 Apr 2004 12:46:17 +0000, Rocky wrote:
    >> I am trying to use strict all the time now.

    >
    > But you don't. Your code doesn't use strict at all. It doesn't use
    > warnings, either;
    >
    > #!/usr/bin/perl
    > #
    > use strict;
    > use warnings;

    I usually put use strict; but didn't here so that the script would work
    >
    >> I have a problem with the following code. When I use strict the value
    >> of $highest won't leave the foreach construct. I know this is by design
    >> but I cannot figure out how make that variable available outside the
    >> loop. Any advice?
    >>
    >> my $dir = "/etc/backup";

    >
    > Needless use of double quotes;

    is this because the value of $dir does not contain another variable and
    does not need to be interpolated?
    >
    > my $dir = '/etc/backup';
    >
    >> opendir DIR1, $dir;

    >
    > Always check if 'open()' and 'opendir()' succeeds;
    >
    > opendir( DIR1, $dir ) or die "$!\n";
    >
    > Eventually;
    >
    > if ( opendir(DIR1, $dir) ) {
    > closedir( DIR1 );
    > }
    > else {
    > # Something bad happened; Error message in $!
    > }
    > Can I open and close a directory before I push it's contents into an

    array?
    >> my @files = readdir(DIR1);
    >> closedir DIR1;
    >> foreach my $filename (@files) {
    >> push(@filenum, $1) if ($filename =~ /^CUX(\d+)\.txt$/); #my
    >> $highest = (sort { $a <=> $b } @filenum)[-1];
    >> }
    >> $highest = (sort { $a <=> $b } @filenum)[-1]; $final = $highest
    >> + $number;
    >> print "CUX00" . "$final" . ".txt\n";

    >
    > You could always make sure that you have the correct set of files when you
    > first read them in with 'readdir';
    >
    > my @files = grep { /^CUX\d+\.txt$/ } readdir( DIR1 );
    >
    > It seems to be that you're trying to find the filename which have the
    > highest number. This could be done like this;
    >
    > opendir( DIR1, $dir ) or die "$!\n";
    > my @files = sort { $a <=> $b } grep { /^CUX\d+\.txt$/ } readdir( DIR1 );
    > closedir( DIR1 );
    >
    > print 'Highest valued filename: ' . $files[-1] . "\n";
    > your kung foo is very strong

    The filename is returned to a korn shell script, but the filename is
    highest + 1 so that the korn shell script can create the file and add
    details about last night's backups.

    >> Also if someone could tell me where to find perldoc regarding "use
    >> strict;" or scoping in general I would appreciate it.

    >
    > I guess 'perldoc strict' would get you going.

    I read the strict perldoc and that was good but I am still missing
    something.
    thank you for your help.
    Rocky, Apr 27, 2004
    #3
  4. Rocky <> wrote:

    > Also if someone could tell me where to find perldoc regarding "use
    > strict;" or scoping in general I would appreciate it.



    perldoc strict

    and

    "Coping with Scoping":

    http://perl.plover.com/FAQs/Namespaces.html


    --
    Tad McClellan SGML consulting
    Perl programming
    Fort Worth, Texas
    Tad McClellan, Apr 27, 2004
    #4
  5. In article <>,
    Rocky <> wrote:

    > I am trying to use strict all the time now. I have a problem with the
    > following code. When I use strict the value of $highest won't leave the
    > foreach construct. I know this is by design but I cannot figure out how
    > make that variable available outside the loop. Any advice?
    >
    > Also if someone could tell me where to find perldoc regarding "use
    > strict;" or scoping in general I would appreciate it.
    >
    >
    > #!/usr/bin/perl
    > my $number = 1;
    > my $dir = "/etc/backup";
    > opendir DIR1, $dir;
    > my @files = readdir(DIR1);
    > closedir DIR1;
    > foreach my $filename (@files)
    > {
    > push(@filenum, $1) if ($filename =~ /^CUX(\d+)\.txt$/);
    > #my $highest = (sort { $a <=> $b } @filenum)[-1];
    > }
    > $highest = (sort { $a <=> $b } @filenum)[-1];
    > $final = $highest + $number;
    > print "CUX00" . "$final" . ".txt\n";


    I _think_ (although I'm not certain), you're asking how to make a
    variable available outside a loop.

    Try this example:

    #!/usr/bin/perl
    use strict;
    use warnings;

    my $highest;
    $highest = 0;
    foreach (1 .. 9) {
    if ($_ > $highest) {
    $highest = $_;
    }
    }

    print $highest, "\n";
    __END__

    The key point (if I understand your question) is to declare the variable
    before you enter the loop (I also initialized it to 0, so I didn't get a
    warning about uninitialized values being used in the comparison). Then
    it remains available once you leave the loop.

    One trick -- make sure you don't rescope the variable inside the loop
    (ie, don't use 'my $highest' inside the loop), because that would hide
    the original $highest from the statements inside the loop.

    HTH,
    Ricky

    --
    Pukku
    Richard Morse, Apr 27, 2004
    #5
  6. Rocky

    Rocky Guest

    On Tue, 27 Apr 2004 10:32:20 -0400, Richard Morse wrote:

    > In article <>,
    > Rocky <> wrote:
    >
    >> I am trying to use strict all the time now. I have a problem with the
    >> following code. When I use strict the value of $highest won't leave the
    >> foreach construct. I know this is by design but I cannot figure out how
    >> make that variable available outside the loop. Any advice?
    >>
    >> Also if someone could tell me where to find perldoc regarding "use
    >> strict;" or scoping in general I would appreciate it.
    >>
    >>
    >> #!/usr/bin/perl
    >> my $number = 1;
    >> my $dir = "/etc/backup";
    >> opendir DIR1, $dir;
    >> my @files = readdir(DIR1);
    >> closedir DIR1;
    >> foreach my $filename (@files)
    >> {
    >> push(@filenum, $1) if ($filename =~ /^CUX(\d+)\.txt$/);
    >> #my $highest = (sort { $a <=> $b } @filenum)[-1];
    >> }
    >> $highest = (sort { $a <=> $b } @filenum)[-1];
    >> $final = $highest + $number;
    >> print "CUX00" . "$final" . ".txt\n";

    >
    > I _think_ (although I'm not certain), you're asking how to make a
    > variable available outside a loop.
    >
    > Try this example:
    >
    > #!/usr/bin/perl
    > use strict;
    > use warnings;
    >
    > my $highest;
    > $highest = 0;
    > foreach (1 .. 9) {
    > if ($_ > $highest) {
    > $highest = $_;
    > }
    > }
    >
    > print $highest, "\n";
    > __END__
    >
    > The key point (if I understand your question) is to declare the variable
    > before you enter the loop (I also initialized it to 0, so I didn't get a
    > warning about uninitialized values being used in the comparison). Then
    > it remains available once you leave the loop.
    >
    > One trick -- make sure you don't rescope the variable inside the loop
    > (ie, don't use 'my $highest' inside the loop), because that would hide
    > the original $highest from the statements inside the loop.
    >
    > HTH,
    > Ricky

    perfect. Thank you
    Rocky, Apr 27, 2004
    #6
  7. Rocky <> wrote:

    > On Tue, 27 Apr 2004 15:00:50 +0200, Tore Aursand wrote:


    >> On Tue, 27 Apr 2004 12:46:17 +0000, Rocky wrote:


    >>> my $dir = "/etc/backup";


    >> Needless use of double quotes;


    > is this because the value of $dir does not contain another
    > variable and does not need to be interpolated?


    Yes. It's a stylistic choice; like proper indentation, it can make your
    code easier to read. Using single quotes indicates to the reader that
    there's no need to look for variable interpolation, and conversely,
    double quotes are a signal to look for variable interpolation.

    It's not a major issue in this case, but using appropriate quoting is a
    good habit to develop.
    David K. Wall, Apr 27, 2004
    #7
  8. Rocky

    Tore Aursand Guest

    On Tue, 27 Apr 2004 13:17:01 +0000, Rocky wrote:
    >>> my $dir = "/etc/backup";


    >> Needless use of double quotes;


    > is this because the value of $dir does not contain another variable and
    > does not need to be interpolated?


    As David already has pointed out (in an excellent way): Yes.

    > Can I open and close a directory before I push it's contents into an
    > array?


    You mean before you _read_ from the directory? No. That doesn't make
    sense, does it?

    opendir( DIR, $dir ) or die "$!\n";
    # Read the contents of <DIR>
    closedir( DIR );

    >> opendir( DIR1, $dir ) or die "$!\n";
    >> my @files = sort {$a <=> $b} grep {/^CUX\d+\.txt$/} readdir(DIR1);
    >> closedir( DIR1 );
    >>
    >> print 'Highest valued filename: ' . $files[-1] . "\n";


    > The filename is returned to a korn shell script, but the filename is
    > highest + 1 so that the korn shell script can create the file and add
    > details about last night's backups.


    No problem adding 1 to the value extracted above.


    --
    Tore Aursand <>
    "What we see depends mainly on what we look for." (Sir John Lubbock)
    Tore Aursand, Apr 27, 2004
    #8
  9. Rocky

    Lack Mr G M Guest

    In article <>, Rocky <> writes:
    |>
    Why do you remember everything, when all you want is the maximum?
    And reading in all file names just to process them sequentially isn't
    necessary.

    my $number = 1;
    opendir DIR1, $dir or die "opendir: $!\n";
    my $highest; # Now defined outside of the loop, so visible after it
    while (1) {
    my $filename = readdir(DIR1);
    last if (not defined $filename);
    if ($filename =~ /^CUX(\d+)\.txt$/)) {
    $highest = $1 if ($1 > $highest);
    }
    }
    closedir DIR1 or die "closedir: $!\n";
    my $final = $highest + $number;
    print "CUX00" . "$final" . ".txt\n";


    --
    --------- Gordon Lack --------------- ------------
    This message *may* reflect my personal opinion. It is *not* intended
    to reflect those of my employer, or anyone else.
    Lack Mr G M, Apr 27, 2004
    #9
  10. Rocky

    Tore Aursand Guest

    On Tue, 27 Apr 2004 18:34:51 +0000, Lack Mr G M wrote:
    > my $number = 1;
    > opendir DIR1, $dir or die "opendir: $!\n";
    > my $highest; # Now defined outside of the loop, so visible after it
    > while (1) {
    > my $filename = readdir(DIR1);
    > last if (not defined $filename);
    > if ($filename =~ /^CUX(\d+)\.txt$/)) {
    > $highest = $1 if ($1 > $highest);
    > }
    > }
    > closedir DIR1 or die "closedir: $!\n";
    > my $final = $highest + $number;
    > print "CUX00" . "$final" . ".txt\n";


    I don't like this code at all. Why do you call readdir() in scalar
    context when there's no need to? Do you fear that there are too many
    files to fit in memory? If so, you could at least have dropped that
    'while (1)' thing;

    while ( my $filename = readdir(DIR) ) {
    if ( $filename =~ /^CUX(\d+)\.txt$/ ) {
    $highest = $1;
    }
    }

    I still prefer the other suggestion I had (in a previous posting), though;
    Using 'sort' and 'grep'.


    --
    Tore Aursand <>
    "First get your facts; then you can distort them at your leisure."
    (Mark Twain)
    Tore Aursand, Apr 27, 2004
    #10
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Talha Oktay
    Replies:
    8
    Views:
    210
  2. David Filmer
    Replies:
    19
    Views:
    227
    Kevin Collins
    May 21, 2004
  3. Ting Wang
    Replies:
    5
    Views:
    163
    John Bokma
    Oct 6, 2005
  4. bernd
    Replies:
    2
    Views:
    632
    bernd
    Jan 26, 2012
  5. Andrew Falanga
    Replies:
    2
    Views:
    194
    Andrew Falanga
    Nov 22, 2008
Loading...

Share This Page