Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Perl > Perl Misc > variable scope and use strict

Reply
Thread Tools

variable scope and use strict

 
 
Rocky
Guest
Posts: n/a
 
      04-27-2004
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";


 
Reply With Quote
 
 
 
 
Tore Aursand
Guest
Posts: n/a
 
      04-27-2004
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 <(E-Mail Removed)>
"War is too serious a matter to entrust to military men." (Georges
Clemenceau)
 
Reply With Quote
 
 
 
 
Rocky
Guest
Posts: n/a
 
      04-27-2004
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.
 
Reply With Quote
 
Tad McClellan
Guest
Posts: n/a
 
      04-27-2004
Rocky <(E-Mail Removed)> 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
http://www.velocityreviews.com/forums/(E-Mail Removed) Perl programming
Fort Worth, Texas
 
Reply With Quote
 
Richard Morse
Guest
Posts: n/a
 
      04-27-2004
In article <(E-Mail Removed)>,
Rocky <(E-Mail Removed)> 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
 
Reply With Quote
 
Rocky
Guest
Posts: n/a
 
      04-27-2004
On Tue, 27 Apr 2004 10:32:20 -0400, Richard Morse wrote:

> In article <(E-Mail Removed)>,
> Rocky <(E-Mail Removed)> 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
 
Reply With Quote
 
David K. Wall
Guest
Posts: n/a
 
      04-27-2004
Rocky <(E-Mail Removed)> 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.

 
Reply With Quote
 
Tore Aursand
Guest
Posts: n/a
 
      04-27-2004
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 <(E-Mail Removed)>
"What we see depends mainly on what we look for." (Sir John Lubbock)
 
Reply With Quote
 
Lack Mr G M
Guest
Posts: n/a
 
      04-27-2004
In article <(E-Mail Removed)>, Rocky <(E-Mail Removed)> 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 --------------- (E-Mail Removed) ------------
This message *may* reflect my personal opinion. It is *not* intended
to reflect those of my employer, or anyone else.
 
Reply With Quote
 
Tore Aursand
Guest
Posts: n/a
 
      04-27-2004
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 <(E-Mail Removed)>
"First get your facts; then you can distort them at your leisure."
(Mark Twain)
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
eval()ing a pattern substitution under 'use strict' and lexical scope bernd Perl Misc 2 01-26-2012 12:07 PM
Having trouble understanding function scope and variable scope Andrew Falanga Javascript 2 11-22-2008 09:23 PM
newbie question about scope, variables, declarations of variables and option strict (as in perl) Talha Oktay Ruby 8 03-08-2006 04:11 PM
How do I scope a variable if the variable name contains a variable? David Filmer Perl Misc 19 05-21-2004 03:55 PM
use strict with an undeclared variable ko Perl Misc 8 09-30-2003 09:36 PM



Advertisments