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
|
|
|
|
|