Home > Archive > PERL Miscellaneous > March 2004 > Variable substitution in variable name
You are viewing an archived Text-only version of the thread.
To view this thread in it's original format and/or if you want to reply to
this thread please [click here]
| Author |
Variable substitution in variable name
|
|
| mshetty 2004-03-30, 9:47 am |
| Hi,
Have the following code where I want to reduce the lines of code:
#Variables to store total file count for each type
$total_cpp_file=0;
$total_h_file=0;
$total_c_file=0;
$total_inp_file=0;
$total_inl_file=0;
$total_hpp_file=0;
$total_cc_file=0;
$total_hh_file=0;
$total_yxx_file=0;
$total_y_file=0;
$total_l_file=0;
find (\&wanted, "S:\\src");
find (\&wanted, "S:\\inc");
sub wanted
{
store_file ($File::Find::name);
}
sub store_file ($)
{
my $name = shift;
if ($name =~ /\.(cpp)$/i)
{
$total_cpp_file++;
push @files_cpp, ($name);
}
elsif ($name =~ /\.(h)$/i)
{
$total_h_file++;
push @files_h, ($name);
}
elsif ($name =~ /\.(c)$/i)
{
$total_c_file++;
push @files_c, ($name);
}
elsif ($name =~ /\.(inp)$/i)
{
$total_inp_file++;
push @files_INP, ($name);
}
elsif ($name =~ /\.(inl)$/i)
{
$total_inl_file++;
push @files_INL, ($name);
}
elsif ($name =~ /\.(hpp)$/i)
{
$total_hpp_file++;
push @files_HPP, ($name);
}
elsif ($name =~ /\.(cc)$/i)
{
$total_cc_file++;
push @files_CC, ($name);
}
elsif ($name =~ /\.(hh)$/i)
{
$total_hh_file++;
push @files_HH, ($name);
}
elsif ($name =~ /\.(yxx)$/i)
{
$total_yxx_file++;
push @files_YXX, ($name);
}
elsif ($name =~ /\.(y)$/i)
{
$total_y_file++;
push @files_Y, ($name);
}
elsif ($name =~ /\.(l)$/i)
{
$total_y_file++;
push @files_L, ($name);
}elsif ($name =~ /\.(dsp)$/i)
{
push @files_dsp, ($name);
}
} #store_file end
IS there a shorter way to write this?
I mean can I store (cpp, h, c, inp, inl, hpp, cc, hh, yxx, y, l) in an
array(file_type and say push @files_$file_type[1]?
Thanks and Regards,
M Shetty
| |
| A. Sinan Unur 2004-03-30, 9:47 am |
| mshetty@mail.com (mshetty) wrote in
news:bfbb8fd4.0403300558.6f63967c@posting.google.com:
> Hi,
>
> Have the following code where I want to reduce the lines of code:
>
> #Variables to store total file count for each type
OK ...
snipped a bunch of lines of noise
> IS there a shorter way to write this?
Use a hash.
my %totals = (
cpp => 0,
hpp => 0
ini => 0,
# ... etc etc
);
print 'Total for cpp: ', $totals{ini}, "\n";
--
A. Sinan Unur
1usa@llenroc.ude (reverse each component for email address)
| |
| Gunnar Hjalmarsson 2004-03-30, 10:44 am |
| mshetty wrote:
> Have the following code where I want to reduce the lines of
> code:
>
> #Variables to store total file count for each type
> $total_cpp_file=0;
> $total_h_file=0;
<snip>
Learn about scoping, and enable strictures.
> if ($name =~ /\.(cpp)$/i)
> {
> $total_cpp_file++;
> push @files_cpp, ($name);
> }
<snip>
> IS there a shorter way to write this?
Absolutely.
The counters should better be hash elements.
my %total;
A hash for storing the file names would also be suitable:
my %files;
Instead of all the if-elsif-else statements, you could do something like:
if ($name =~ /\.(\w+)$/) {
$total{$1}++;
push @{ $files{$1} }, $name;
}
That would make %files a hash of arrays.
HTH
--
Gunnar Hjalmarsson
Email: http://www.gunnar.cc/cgi-bin/contact.pl
| |
| Paul Lalli 2004-03-30, 10:44 am |
| On Tue, 30 Mar 2004, mshetty wrote:
>
> Hi,
>
> Have the following code where I want to reduce the lines of code:
>
> #Variables to store total file count for each type
> $total_cpp_file=0;
> $total_h_file=0;
> $total_c_file=0;
> $total_inp_file=0;
> $total_inl_file=0;
> $total_hpp_file=0;
> $total_cc_file=0;
> $total_hh_file=0;
> $total_yxx_file=0;
> $total_y_file=0;
> $total_l_file=0;
>
> find (\&wanted, "S:\\src");
> find (\&wanted, "S:\\inc");
> sub wanted
> {
> store_file ($File::Find::name);
> }
>
> sub store_file ($)
> {
> my $name = shift;
> if ($name =~ /\.(cpp)$/i)
> {
> $total_cpp_file++;
> push @files_cpp, ($name);
> }
<etc>
> IS there a shorter way to write this?
>
> I mean can I store (cpp, h, c, inp, inl, hpp, cc, hh, yxx, y, l) in an
> array(file_type and say push @files_$file_type[1]?
>
> Thanks and Regards,
> M Shetty
>
Use a hash of arrays.
my %files;
sub store_file {
my $name = shift;
if ($name =~ /\.(.*)$/i)){
push @{$files{$1}}, $name;
} else {
warn "Unknown file type: $name\n";
}
}
sub print_files {
foreach (keys %files){
local $, = ", ";
print "There are " . @{$files{$_}} . " $_ files:\n";
print @{$files{$_}};
}
}
HTH,
Paul Lalli
| |
| Web Surfer 2004-03-30, 11:43 am |
| [This followup was posted to comp.lang.perl.misc]
In article <bfbb8fd4.0403300558.6f63967c@posting.google.com>,
mshetty@mail.com says...
> Hi,
>
> Have the following code where I want to reduce the lines of code:
>
> #Variables to store total file count for each type
> $total_cpp_file=0;
> $total_h_file=0;
> $total_c_file=0;
> $total_inp_file=0;
> $total_inl_file=0;
> $total_hpp_file=0;
> $total_cc_file=0;
> $total_hh_file=0;
> $total_yxx_file=0;
> $total_y_file=0;
> $total_l_file=0;
>
> find (\&wanted, "S:\\src");
> find (\&wanted, "S:\\inc");
> sub wanted
> {
> store_file ($File::Find::name);
> }
>
> sub store_file ($)
> {
> my $name = shift;
> if ($name =~ /\.(cpp)$/i)
> {
> $total_cpp_file++;
> push @files_cpp, ($name);
> }
> elsif ($name =~ /\.(h)$/i)
> {
> $total_h_file++;
> push @files_h, ($name);
> }
> elsif ($name =~ /\.(c)$/i)
> {
> $total_c_file++;
> push @files_c, ($name);
> }
> elsif ($name =~ /\.(inp)$/i)
> {
> $total_inp_file++;
> push @files_INP, ($name);
> }
> elsif ($name =~ /\.(inl)$/i)
> {
> $total_inl_file++;
You could use a hash.
my %totals = ( "cpp" => 0 , "h" => 0 , "c" => 0 );
# of course you will need to code the entries for ALL possible filename
# extensions
To increment an element :
$totals{"cpp"} += 1;
| |
| Anno Siegel 2004-03-30, 11:43 am |
| Gunnar Hjalmarsson <noreply@gunnar.cc> wrote in comp.lang.perl.misc:
> mshetty wrote:
[...]
[color=darkred]
> Instead of all the if-elsif-else statements, you could do something like:
>
> if ($name =~ /\.(\w+)$/) {
> $total{$1}++;
> push @{ $files{$1} }, $name;
> }
The %total hash is not needed any more. The count can be read off the
arrays:
my $total = @{ $files{ $key}}
Anno
| |
| Gunnar Hjalmarsson 2004-03-30, 12:39 pm |
| Web Surfer wrote:
> You could use a hash.
Agreed.
> my %totals = ( "cpp" => 0 , "h" => 0 , "c" => 0 );
> # of course you will need to code the entries for ALL possible
> # filename extensions
No. Please read the rest of the thread before posting your advice.
--
Gunnar Hjalmarsson
Email: http://www.gunnar.cc/cgi-bin/contact.pl
| |
| John W. Krahn 2004-03-30, 6:36 pm |
| mshetty wrote:
>
> Hi,
>
> Have the following code where I want to reduce the lines of code:
>
> #Variables to store total file count for each type
> $total_cpp_file=0;
> $total_h_file=0;
> $total_c_file=0;
> $total_inp_file=0;
> $total_inl_file=0;
> $total_hpp_file=0;
> $total_cc_file=0;
> $total_hh_file=0;
> $total_yxx_file=0;
> $total_y_file=0;
> $total_l_file=0;
>
> find (\&wanted, "S:\\src");
> find (\&wanted, "S:\\inc");
> sub wanted
> {
> store_file ($File::Find::name);
> }
>
> sub store_file ($)
> {
> my $name = shift;
> if ($name =~ /\.(cpp)$/i)
> {
> $total_cpp_file++;
> push @files_cpp, ($name);
> }
> elsif ($name =~ /\.(h)$/i)
> {
> $total_h_file++;
> push @files_h, ($name);
> }
> elsif ($name =~ /\.(c)$/i)
> {
> $total_c_file++;
> push @files_c, ($name);
> }
> elsif ($name =~ /\.(inp)$/i)
> {
> $total_inp_file++;
> push @files_INP, ($name);
> }
> elsif ($name =~ /\.(inl)$/i)
> {
> $total_inl_file++;
> push @files_INL, ($name);
> }
> elsif ($name =~ /\.(hpp)$/i)
> {
> $total_hpp_file++;
> push @files_HPP, ($name);
> }
> elsif ($name =~ /\.(cc)$/i)
> {
> $total_cc_file++;
> push @files_CC, ($name);
> }
> elsif ($name =~ /\.(hh)$/i)
> {
> $total_hh_file++;
> push @files_HH, ($name);
> }
> elsif ($name =~ /\.(yxx)$/i)
> {
> $total_yxx_file++;
> push @files_YXX, ($name);
> }
> elsif ($name =~ /\.(y)$/i)
> {
> $total_y_file++;
> push @files_Y, ($name);
> }
> elsif ($name =~ /\.(l)$/i)
> {
> $total_y_file++;
> push @files_L, ($name);
> }elsif ($name =~ /\.(dsp)$/i)
> {
> push @files_dsp, ($name);
> }
>
> } #store_file end
>
> IS there a shorter way to write this?
>
> I mean can I store (cpp, h, c, inp, inl, hpp, cc, hh, yxx, y, l) in an
> array(file_type and say push @files_$file_type[1]?
Yes there is a shorter way:
use warnings;
use strict;
use File::Find;
my @types = qw( cpp hpp inp inl yxx cc hh c h l y );
# types must have longest first to work correctly
my $regex = qr/@{[ join '|', @types ]}/i;
my %totals;
find( sub{
return unless /\.($regex)$/;
push @{ $totals{ $1 } }, $File::Find::name;
}, 'S:/src', 'S:/inc' );
print <<HEADER;
Type Count
----------
HEADER
for my $type ( sort keys %totals ) {
printf "%4s %d\n", $type, @{ $totals{ $type } };
}
__END__
John
--
use Perl;
program
fulfillment
|
|
|
|
|