For Programmers: Free Programming Magazines  


Home > Archive > PERL Beginners > May 2007 > Can't sort error out; strict refs









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 Can't sort error out; strict refs
Mathew Snyder

2007-05-14, 7:58 am

I'm passing two hash references into a subroutine. One hash is in the format of
$dept{$env}{$user}. This contains an amount of time spent by each user on a
customer ($env). The second hash is in the format of
$ticCount{$env}{$user}{$ticID}. This contains a running count of how many times
a user worked on ticket '$ticID' which belongs to customer '$env'. I won't be
using that number though. What I need is the number of tickets worked on so I
simply use 'scalar keys' on this hash.

The problem I'm encountering though, is that I'm passing the hashes into my
subroutine as references. When I get to the statement that gets the key count I
get an error: "Can't use string ("2") as a HASH ref while "strict refs" in use
at user_timesheet.pl line 63." Presumably, 2 is the number of keys at
$ticCount{$env}{$user}{$ticID}.

sub average {
my ($users, $count) = @_;
my %userAvg;
foreach my $env (keys %$count) {
foreach my $user (keys %{ $count->{$env} }) {
foreach my $ticID (keys %{ $count->{$env}->{$user} }) {
my $ticCount = scalar keys %{
$count->{$env}->{$user}->{$ticID}};
my @meantemp;
my @meantime;
my @endtime;
my $temp = $users->{$env}->{$user};
@meantemp = split /\./, ($temp / $ticCount);
# If the time divided by the number of tickets
has a decimal
# value round up if that value is greater than
# 0.5. This will give an even number of minutes
to figure
# out the mean time with.
if ($meantemp[1]) {
if ($meantemp[1] >= 5) {
$meantemp[0]++;
}
}
@meantime = split /\./, ($meantemp[0] / 60);
$endtime[0] = $meantime[0];
$endtime[1] = $meantemp[0] % 60;
$userAvg{$env}{$user} = sprintf '%d:%02d',
@endtime[0,1];
}
}
}
return %userAvg;
}

I've run this in the debugger and when I get to the line which assigns $ticCount
I try to print it out and it's just blank. If I keep hitting enter it just
returns to a blank line. I get the error when I continue to the next line with 'c'.

Mathew
--
Keep up with me and what I'm up to: http://theillien.blogspot.com
Paul Lalli

2007-05-14, 7:58 am

On May 14, 5:30 am, theill...@yahoo.com (Mathew Snyder) wrote:
> I'm passing two hash references into a subroutine. One hash is in the format of
> $dept{$env}{$user}. This contains an amount of time spent by each user on a
> customer ($env). The second hash is in the format of
> $ticCount{$env}{$user}{$ticID}. This contains a running count of how many times
> a user worked on ticket '$ticID' which belongs to customer '$env'. I won't be
> using that number though. What I need is the number of tickets worked on so I
> simply use 'scalar keys' on this hash.
>
> The problem I'm encountering though, is that I'm passing the hashes into my
> subroutine as references. When I get to the statement that gets the key count I
> get an error: "Can't use string ("2") as a HASH ref while "strict refs" in use
> at user_timesheet.pl line 63." Presumably, 2 is the number of keys at
> $ticCount{$env}{$user}{$ticID}.
>
> sub average {
> my ($users, $count) = @_;
> my %userAvg;
> foreach my $env (keys %$count) {
> foreach my $user (keys %{ $count->{$env} }) {
> foreach my $ticID (keys %{ $count->{$env}->{$user} }) {
> my $ticCount = scalar keys %{
> $count->{$env}->{$user}->{$ticID}};
> my @meantemp;
> my @meantime;
> my @endtime;
> my $temp = $users->{$env}->{$user};
> @meantemp = split /\./, ($temp / $ticCount);
> # If the time divided by the number of tickets
> has a decimal
> # value round up if that value is greater than
> # 0.5. This will give an even number of minutes
> to figure
> # out the mean time with.
> if ($meantemp[1]) {
> if ($meantemp[1] >= 5) {
> $meantemp[0]++;
> }
> }
> @meantime = split /\./, ($meantemp[0] / 60);
> $endtime[0] = $meantime[0];
> $endtime[1] = $meantemp[0] % 60;
> $userAvg{$env}{$user} = sprintf '%d:%02d',
> @endtime[0,1];
> }
> }
> }
> return %userAvg;
>
> }
>
> I've run this in the debugger and when I get to the line which assigns $ticCount
> I try to print it out and it's just blank. If I keep hitting enter it just
> returns to a blank line. I get the error when I continue to the next line with 'c'.


Without knowing what line above is line 63, I'm not going to spend the
time guessing which line is wrong. Why don't you just print out the
entire structure with Data::Dumper and figure out what's different
between what it is and what you expect?

use Data::Dumper;
print Dumper($count);

Paul Lalli

Rob Dixon

2007-05-14, 7:58 am

Mathew Snyder wrote:
>
> I'm passing two hash references into a subroutine. One hash is in the format of
> $dept{$env}{$user}. This contains an amount of time spent by each user on a
> customer ($env). The second hash is in the format of
> $ticCount{$env}{$user}{$ticID}. This contains a running count of how many times
> a user worked on ticket '$ticID' which belongs to customer '$env'. I won't be
> using that number though. What I need is the number of tickets worked on so I
> simply use 'scalar keys' on this hash.
>
> The problem I'm encountering though, is that I'm passing the hashes into my
> subroutine as references. When I get to the statement that gets the key count I
> get an error: "Can't use string ("2") as a HASH ref while "strict refs" in use
> at user_timesheet.pl line 63." Presumably, 2 is the number of keys at
> $ticCount{$env}{$user}{$ticID}.
>
> sub average {
>
> my ($users, $count) = @_;
> my %userAvg;
>
> foreach my $env (keys %$count) {
> foreach my $user (keys %{ $count->{$env} }) {
> foreach my $ticID (keys %{ $count->{$env}->{$user} }) {
>
> my $ticCount = scalar keys %{$count->{$env}->{$user}->{$ticID}};
>
> my @meantemp;
> my @meantime;
> my @endtime;
>
> my $temp = $users->{$env}->{$user};
> @meantemp = split /\./, ($temp / $ticCount);
>
> # If the time divided by the number of tickets has a decimal
> # value round up if that value is greater than
> # 0.5. This will give an even number of minutes to figure
> # out the mean time with.
> if ($meantemp[1]) {
> if ($meantemp[1] >= 5) {
> $meantemp[0]++;
> }
> }
> @meantime = split /\./, ($meantemp[0] / 60);
> $endtime[0] = $meantime[0];
> $endtime[1] = $meantemp[0] % 60;
> $userAvg{$env}{$user} = sprintf '%d:%02d', @endtime[0,1];
> }
> }
> }
>
> return %userAvg;
> }
>
> I've run this in the debugger and when I get to the line which assigns $ticCount
> I try to print it out and it's just blank. If I keep hitting enter it just
> returns to a blank line. I get the error when I continue to the next line with 'c'.


Hi Mathew

First of all, you can replace

$count->{$env}->{$user}->{$ticID}

with

$count->{$env}{$user}{$ticID}

and Perl will infer the indirection. It makes for neater code.

The reason for your problem is that you've gone too far down in the hash structure. You
said that $count->{$env}{$user}{$ticID} is a "count of how many times a user worked on
[a] ticket", in this case 2. so you're then trying to do

my $ticCount = scalar keys %{2};

which is failing.

Finally, you can round more efficiently by using int(x + 0.5). I suggest something
like this (untested):

sub average {

my ($users, $count) = @_;
my %userAvg;

foreach my $env (keys %$count) {
foreach my $user (keys %{ $count->{$env} }) {

my $ticCount = scalar keys %{$count->{$env}{$user}};

my $time = $users->{$env}{$user};
my $meantime = int($time / $ticCount + 0.5);

$userAvg{$env}{$user} = sprintf '%d:%02d',
int($meantime / 60), $meantime % 60;
}
}

return %userAvg;
}

HTH,

Rob
Mathew

2007-05-16, 7:58 am



Rob Dixon wrote:
> Mathew Snyder wrote:
>
> Hi Mathew
>
> First of all, you can replace
>
> $count->{$env}->{$user}->{$ticID}
>
> with
>
> $count->{$env}{$user}{$ticID}
>
> and Perl will infer the indirection. It makes for neater code.
>
> The reason for your problem is that you've gone too far down in the hash
> structure. You
> said that $count->{$env}{$user}{$ticID} is a "count of how many times a
> user worked on
> [a] ticket", in this case 2. so you're then trying to do
>
> my $ticCount = scalar keys %{2};
>
> which is failing.
>
> Finally, you can round more efficiently by using int(x + 0.5). I suggest
> something
> like this (untested):
>
> sub average {
>
> my ($users, $count) = @_;
> my %userAvg;
>
> foreach my $env (keys %$count) {
> foreach my $user (keys %{ $count->{$env} }) {
>
> my $ticCount = scalar keys %{$count->{$env}{$user}};
>
> my $time = $users->{$env}{$user};
> my $meantime = int($time / $ticCount + 0.5);
>
> $userAvg{$env}{$user} = sprintf '%d:%02d',
> int($meantime / 60), $meantime % 60;
> }
> }
>
> return %userAvg;
> }
>
> HTH,
>
> Rob
>


Thanks. That did the trick. I'll be working with your provided method
for rounding up tonight when I get to work.

Mathew
Sponsored Links







Also available: Server administration forum archive | Web Design forum archive | Software forum archive | Hardware reviews archive

Copyright 2008 codecomments.com