steph_bow has asked for the wisdom of the Perl Monks concerning the following question:


Hello ,thanks for the reply for a precedent question.

Following this, I tried to apply the advice.
but my programm keeps sending me the message :
%M4 needs explicit name

but I never use %M4, I use $M4

Could you give me some more advice please ? Thanks a lot

My code needs as entry a file which is composed of three columns
#!/usr/bin/perl use strict; ###################################### # variables ########### # this is the TV my $tv; # profile is the CTFM or FTFM my $profile; # $reg is the name of the regulation my $reg; # $reason is the reason of the regulation my $reason; # $fmp is the name of the FMP my $fmp; # $date is the date my $date; # ${autre_date} is the same as {date} but it is rearranged. my $autre_date; # ${duration_reg} is the length of the regulation, which is equal to t +he length of the CUT file + the count_parameter : 60 or 20 my $duration_reg; my $count_parameter; my $filename; my $entry_count; my $flow_rate; my $Duration; my $q; # we introduce ${mod_target} because we have to compare the target to +a relative flow $q # the target ranges from 0 to 50, so the ${mod_target} ranges from 0 t +o 0.5 # which is the same order of magnitude as the $q my $mod_target; #there are two arguments $count_parameter=$ARGV[1]; $Duration = 0; $duration_reg=0; if ($ARGV[0] =~ /^(\d\d\d\d)(\d\d)(\d\d)_([^_]*)_([^_]*)_([^_]*)_( +[^_]*)_([^_]*)_(.*)$/) { $tv="$4"; $profile="$5"; $reg="$6"; $reason="$7"; $fmp="$8"; $date="$3/$2/$1"; $autre_date="$3"."$2"."$1"; } # what follows aims at calculating the time by looking for the number +of lines open (INFILE,"$ARGV[0]"); while (<INFILE>) { $duration_reg++; } # after summing up the number of lines in the CUT file, you have to ad +d the count_parameter $duration_reg=$duration_reg+$count_parameter-1; close INFILE; open (INFILE,"$ARGV[0]"); $filename = "M4_all_target"."_$profile"."_$reg"."_$autre_date"."_$reas +on"."_$duration_reg"."_$fmp"; open (OUTFILE, ">$filename.txt"); while(<INFILE>) { if (/^(\d+);(\d+);(\d+)\n$/) { $entry_count=$2; $flow_rate=$3; } $q=$entry_count/$flow_rate-1; $Duration = $Duration + 1; my @TARGET = (0..50); my $target; my $M4; my $M4_compteur; foreach $target(@TARGET){ ${mod_target}=${target}/100; if ($q > ${mod_target}) { $M4_compteur{$target} = 1; } else { $M4_compteur{$target} = 0; } $M4{$target} = $M4{$target} + $M4_compteur{$target}; } } foreach $target(@TARGET){ $M4{$target} = $M4{$target}/$Duration; } print OUTFILE "$reg;;$M4{0};$M4{1};$M4{2};$M4{3};$M4{4};$M4{5};$M4{6}; +$M4{7};$M4{8};$M4{9};$M4{10};$M4{11};$M4{12};$M4{13};$M4{14};$M4{15}; +$M4{16};$M4{17};$M4{18};$M4{19};$M4{20};$M4{21};$M4{22};$M4{23};$M4{2 +4};$M4{25};$M4{26};$M4{27};$M4{28};$M4{29};$M4{30};$M4{31};$M4{32};$M +4{33};$M4{34};$M4{35};$M4{36};$M4{37};$M4{38};$M4{39};$M4{40};$M4{41} +;$M4{42};$M4{43};$M4{44};$M4{45};$M4{46};$M4{47};$M4{48};$M4{49};$M4{ +50};$tv;$reg;$date;$reason;$duration_reg;$fmp\n"; close INFILE; close OUTFILE;

20070730 Janitored by Corion: Added <readmore> tag, as per Writeup Formatting Tips

Replies are listed 'Best First'.
Re: right use of a hash table
by friedo (Prior) on Jul 19, 2007 at 15:22 UTC
    but I never use %M4, I use $M4

    $M4 is a scalar, and %M4 is a hash. You are clearly using a hash, but you declare a scalar with my $M4. Use my %M4 instead.

Re: right use of a hash table
by philcrow (Priest) on Jul 19, 2007 at 15:24 UTC
    When you refer to an element of a hash you say $hash_name{'key'}, but to refer to the whole hash you must say %hash_name. So change your mys:
    my %M4; my %M4_compteur;
    Phil
    The Gantry Web Framework Book is now available.
      Thanks a lot for your advice. It works now !
Re: right use of a hash table
by monkey_boy (Priest) on Jul 19, 2007 at 15:22 UTC
    change
     my $M4;
    to
     my %M4;
    Individual hash elements are accessed/set like so  $M4{foo} = 'bar'; but Hashes are declared like  my %M4 = (foo => 'bar', me => 'you' );


    This is not a Signature...
Re: right use of a hash table
by injunjoel (Priest) on Jul 19, 2007 at 15:27 UTC
    steph_bow,
    You are initializing a scalar $M4 yet you are using it like a hash %M4 with your $M4{$target} code. You are saying give me the scalar ($) in the %M4 hash at the key $target, whatever that happens to be. Though a hash is initialized with the % symbol it contains scalars as values. Thus when you refer to an element in the hash (be it a number, string, character or reference to something else) you call it in its resultant context, in this case a scalar (though you could also pull out an array or another hash if that is what you stored a reference to in there) . If you want to use a scalar as a reference to an anonymous hash you would need to change your assignments to utilize the -> so $M4_compteur{$target} becomes $M4_compteur->{$target} for both assignment and retrieval. Does that make sense?
    perldata, perldsc and perlref might all be of help. Happy reading!

    -InjunJoel
    "I do not feel obliged to believe that the same God who endowed us with sense, reason and intellect has intended us to forego their use." -Galileo
Re: right use of a hash table
by swampyankee (Parson) on Jul 19, 2007 at 16:01 UTC

    You're referring to %M4 on this line:

    $M4{$target} = $M4{$target} + $M4_compteur{$target};
    and this one
    $M4{$target} = $M4{$target}/$Duration;
    but declare only $M4, on this line:
    my $M4;

    It appears you are doing the same thing with the variable $M4_compteur.

    Try changing

    my $M4; my $M4_compteur;

    to

    my %M4; my %M4_compteur;

    The sigils ($, %, &, *, @) are important. I also find them slightly confusing, as $this, %this, @this, and &this are completely distinct, but the elements of %this and @this are referenced as $this{one} and $this$one. To ease my confusion, I tend to avoid giving scalars, arrays, hashes, and functions names that are the same or too similar.


    emc

    Information about American English usage here and here.

    Any New York City or Connecticut area jobs? I'm currently unemployed.