Home > Archive > PERL Beginners > March 2007 > hash referrences and such
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 |
hash referrences and such
|
|
| Mathew Snyder 2007-03-21, 5:34 am |
| I have a problem printing out a hash. This is the script I'm working with:
#!/usr/bin/perl
use warnings;
use strict;
use lib '/usr/local/rt-3.6.3/lib';
use lib '/usr/local/rt-3.6.3/local/lib';
use RT;
use RT::Tickets;
RT::LoadConfig();
RT::Init();
my $tix = new RT::Tickets(RT::SystemUser);
$tix->FromSQL('Queue = "CustomerCare" OR Status = "resolved" OR Status = "open"');
my $timeworked = {};
my %env;
while (my $ticket = $tix->Next) {
my $customer = $ticket->FirstCustomFieldValue('Environment');
unless ($customer) {warn "warning" . $ticket->id. "no profile"; next}
my $transactions = $ticket->Transactions;
while (my $transaction = $transactions->Next) {
next unless ($transaction->TimeTaken);
$timeworked = $env{$transaction->Creator}{$transaction->TimeTaken};
print "Working on " . $ticket->id . "\n";
foreach my $key (keys %$env) {
print $key . " -> " . $env{$key} . "\n";
}
}
}
When I print the hash all I get is a reference. I can't seem to figure out how
to get the actual contents. I've tried using \$, %$, %{$env} and %{env}. Some
cause errors and some simply print out the reference. I'm not even sure I'm
doing the "$timeworked = " line correctly. Can someone help me out with this
please?
Thanks
Mathew
| |
| Jeff Pang 2007-03-21, 5:34 am |
|
> foreach my $key (keys %$env) {
> print $key . " -> " . $env{$key} . "\n";
> }
Hello,
For a quick look,the codes above may not work.
Since $env is a hash reference,so you can't say $env{$key} to access the hash's value.
It may change to:
print $key . " -> " . $env->{$key} . "\n";
| |
| Mathew Snyder 2007-03-21, 5:34 am |
| Also, I've read the *perldsc* perldoc and it didn't help undo my confusion.
If we don't protect the freedom of speech, how will we know who the assholes are?
http://theillien.blogspot.com
Mathew Snyder wrote:
> I have a problem printing out a hash. This is the script I'm working with:
> #!/usr/bin/perl
>
> use warnings;
> use strict;
> use lib '/usr/local/rt-3.6.3/lib';
> use lib '/usr/local/rt-3.6.3/local/lib';
> use RT;
> use RT::Tickets;
>
> RT::LoadConfig();
> RT::Init();
>
> my $tix = new RT::Tickets(RT::SystemUser);
> $tix->FromSQL('Queue = "CustomerCare" OR Status = "resolved" OR Status = "open"');
>
> my $timeworked = {};
> my %env;
>
> while (my $ticket = $tix->Next) {
> my $customer = $ticket->FirstCustomFieldValue('Environment');
> unless ($customer) {warn "warning" . $ticket->id. "no profile"; next}
> my $transactions = $ticket->Transactions;
> while (my $transaction = $transactions->Next) {
> next unless ($transaction->TimeTaken);
> $timeworked = $env{$transaction->Creator}{$transaction->TimeTaken};
> print "Working on " . $ticket->id . "\n";
> foreach my $key (keys %$env) {
> print $key . " -> " . $env{$key} . "\n";
> }
> }
>
> }
>
> When I print the hash all I get is a reference. I can't seem to figure out how
> to get the actual contents. I've tried using \$, %$, %{$env} and %{env}. Some
> cause errors and some simply print out the reference. I'm not even sure I'm
> doing the "$timeworked = " line correctly. Can someone help me out with this
> please?
>
> Thanks
> Mathew
>
| |
| Mathew Snyder 2007-03-21, 5:34 am |
| Also, I've read the *perldsc* perldoc and it didn't help undo my confusion.
Mathew
Mathew Snyder wrote:
> I have a problem printing out a hash. This is the script I'm working with:
> #!/usr/bin/perl
>
> use warnings;
> use strict;
> use lib '/usr/local/rt-3.6.3/lib';
> use lib '/usr/local/rt-3.6.3/local/lib';
> use RT;
> use RT::Tickets;
>
> RT::LoadConfig();
> RT::Init();
>
> my $tix = new RT::Tickets(RT::SystemUser);
> $tix->FromSQL('Queue = "CustomerCare" OR Status = "resolved" OR Status = "open"');
>
> my $timeworked = {};
> my %env;
>
> while (my $ticket = $tix->Next) {
> my $customer = $ticket->FirstCustomFieldValue('Environment');
> unless ($customer) {warn "warning" . $ticket->id. "no profile"; next}
> my $transactions = $ticket->Transactions;
> while (my $transaction = $transactions->Next) {
> next unless ($transaction->TimeTaken);
> $timeworked = $env{$transaction->Creator}{$transaction->TimeTaken};
> print "Working on " . $ticket->id . "\n";
> foreach my $key (keys %$env) {
> print $key . " -> " . $env{$key} . "\n";
> }
> }
>
> }
>
> When I print the hash all I get is a reference. I can't seem to figure out how
> to get the actual contents. I've tried using \$, %$, %{$env} and %{env}. Some
> cause errors and some simply print out the reference. I'm not even sure I'm
> doing the "$timeworked = " line correctly. Can someone help me out with this
> please?
>
> Thanks
> Mathew
>
| |
| Mathew Snyder 2007-03-21, 5:34 am |
| Jeff Pang wrote:
>
> Hello,
>
> For a quick look,the codes above may not work.
> Since $env is a hash reference,so you can't say $env{$key} to access the hash's value.
> It may change to:
>
> print $key . " -> " . $env->{$key} . "\n";
>
That isn't working either. It is complaining about $env not being declared. I
replaced it with %{env}->{$key} but it said it was deprecated. It then
proceeded to print out the references.
Mathew
| |
| Jeff Pang 2007-03-21, 5:34 am |
|
>
>Jeff Pang wrote:
>
>That isn't working either. It is complaining about $env not being declared. I
>replaced it with %{env}->{$key} but it said it was deprecated. It then
>proceeded to print out the references.
>
Hi,
Since %env is clearly a hash not a hash referenct,why you write this below?
> foreach my $key (keys %$env) {
Give a try to replace it to:
foreach my $key (keys %env) {
Good luck!
--
http://home.arcor.de/jeffpang/
| |
| Mathew Snyder 2007-03-21, 5:34 am |
| Jeff Pang wrote:
>
> Hi,
>
> Since %env is clearly a hash not a hash referenct,why you write this below?
>
> Give a try to replace it to:
>
> foreach my $key (keys %env) {
>
> Good luck!
>
> --
> http://home.arcor.de/jeffpang/
>
Yes, did that already. The complaint is coming in regards to *print* line. It
doesn't like anything I do there.
Mathew
| |
| Rob Dixon 2007-03-21, 5:34 am |
| Mathew Snyder wrote:
>
> I have a problem printing out a hash. This is the script I'm working with:
> #!/usr/bin/perl
>
> use warnings;
> use strict;
> use lib '/usr/local/rt-3.6.3/lib';
> use lib '/usr/local/rt-3.6.3/local/lib';
> use RT;
> use RT::Tickets;
>
> RT::LoadConfig();
> RT::Init();
>
> my $tix = new RT::Tickets(RT::SystemUser);
> $tix->FromSQL('Queue = "CustomerCare" OR Status = "resolved" OR Status = "open"');
>
> my $timeworked = {};
> my %env;
>
> while (my $ticket = $tix->Next) {
> my $customer = $ticket->FirstCustomFieldValue('Environment');
> unless ($customer) {warn "warning" . $ticket->id. "no profile"; next}
> my $transactions = $ticket->Transactions;
> while (my $transaction = $transactions->Next) {
> next unless ($transaction->TimeTaken);
> $timeworked = $env{$transaction->Creator}{$transaction->TimeTaken};
> print "Working on " . $ticket->id . "\n";
> foreach my $key (keys %$env) {
> print $key . " -> " . $env{$key} . "\n";
> }
> }
>
> }
>
> When I print the hash all I get is a reference. I can't seem to figure out how
> to get the actual contents. I've tried using \$, %$, %{$env} and %{env}. Some
> cause errors and some simply print out the reference. I'm not even sure I'm
> doing the "$timeworked = " line correctly. Can someone help me out with this
> please?
Nothing is ever put into the %env hash. If it had contents you
could display them using
foreach my $key (keys %env) {
printf "%s -> %s\n", $key, $env{$key};
}
but as it stands this will print nothing. I can't even work out what you expect to
be in there, so I can't help you with the $timeworked assigment. Tell us a little
bit more please.
Rob
| |
| Mathew Snyder 2007-03-21, 5:34 am |
| Rob Dixon wrote:
> Mathew Snyder wrote:
>
> Nothing is ever put into the %env hash. If it had contents you could
> display them using
>
> foreach my $key (keys %env) {
> printf "%s -> %s\n", $key, $env{$key};
> }
>
> but as it stands this will print nothing. I can't even work out what you
> expect to
> be in there, so I can't help you with the $timeworked assigment. Tell us
> a little
> bit more please.
>
> Rob
>
Essentially, this is a reporting script for our trouble ticket system. Each
ticket has several transactions associated with it that actually make up the
ticket. Some of those transactions are the addition of time spent on working on
the ticket by its owner.
What I am trying to do is create a hash of customers which will contain a hash
of each user and the total time spent on the customer. First, creating the
customer hash and then, for each customer, look at its tickets and keep a
running total of time spent on the customer for each user.
Mathew
| |
| Chas Owens 2007-03-21, 5:34 am |
| On 3/20/07, Mathew Snyder <theillien@yahoo.com> wrote:
snip
> $timeworked = $env{$transaction->Creator}{$transaction->TimeTaken};
snip
From this line you can see that %env is a HoH (hash of hashes). This
means that if you want to print it out you need two loops: one for the
first layer and one for the second.
for my $first_key (sort keys %env) {
for my $second_key (sort keys %{$env{$first_key}}) {
print "$first_key :: $second_key => $env{$first_key}{$second_key}\n";
}
}
| |
| Uri Guttman 2007-03-21, 5:34 am |
| >>>>> "MS" == Mathew Snyder <theillien@yahoo.com> writes:
MS> I have a problem printing out a hash. This is the script I'm working with:
MS> my %env;
MS> $timeworked = $env{$transaction->Creator}{$transaction->TimeTaken};
you have never assigned anything into %env. so why do you access it? and
since you access it 2 levels deep, perl will autovivify the top
level. but the next level is empty and so you will see a bunch of hash
refs with no data in them. and this also means that $timeworked will
never have a defined value.
MS> When I print the hash all I get is a reference. I can't seem to
MS> figure out how to get the actual contents. I've tried using \$,
MS> %$, %{$env} and %{env}. Some cause errors and some simply print
MS> out the reference. I'm not even sure I'm doing the "$timeworked =
MS> " line correctly. Can someone help me out with this please?
what do you expect to see inside %env? it is just a bunch of hash refs
which is what you do see. it isn't a problem with your printing but that
you never put any real data in %env.
uri
--
Uri Guttman ------ uri@stemsystems.com -------- http://www.stemsystems.com
--Perl Consulting, Stem Development, Systems Architecture, Design and Coding-
Search or Offer Perl Jobs ---------------------------- http://jobs.perl.org
| |
| Uri Guttman 2007-03-21, 5:34 am |
| >>>>> "CO" == Chas Owens <chas.owens@gmail.com> writes:
CO> On 3/20/07, Mathew Snyder <theillien@yahoo.com> wrote:
CO> snip[color=darkred]
CO> snip
CO> From this line you can see that %env is a HoH (hash of hashes). This
CO> means that if you want to print it out you need two loops: one for the
CO> first layer and one for the second.
CO> for my $first_key (sort keys %env) {
CO> for my $second_key (sort keys %{$env{$first_key}}) {
CO> print "$first_key :: $second_key => $env{$first_key}{$second_key}\n";
CO> }
CO> }
see my other post. there is no second level in that hash since he never
stuffs anything in it. all you will see is the top level hash refs that
come from autovivification.
uri
--
Uri Guttman ------ uri@stemsystems.com -------- http://www.stemsystems.com
--Perl Consulting, Stem Development, Systems Architecture, Design and Coding-
Search or Offer Perl Jobs ---------------------------- http://jobs.perl.org
| |
| Mathew Snyder 2007-03-21, 5:34 am |
| Chas Owens wrote:
> On 3/20/07, Mathew Snyder <theillien@yahoo.com> wrote:
> snip
> snip
>
> means that if you want to print it out you need two loops: one for the
> first layer and one for the second.
>
> for my $first_key (sort keys %env) {
> for my $second_key (sort keys %{$env{$first_key}}) {
> print "$first_key :: $second_key =>
> $env{$first_key}{$second_key}\n";
> }
> }
>
Thanks Chas. I had tried that but as Rob mentioned earlier, it appears nothing
is being placed in the hash in the first place.
Mathew
| |
| Mathew Snyder 2007-03-21, 5:34 am |
| Rob Dixon wrote:
> Mathew Snyder wrote:
>
> Nothing is ever put into the %env hash. If it had contents you could
> display them using
>
> foreach my $key (keys %env) {
> printf "%s -> %s\n", $key, $env{$key};
> }
>
> but as it stands this will print nothing. I can't even work out what you
> expect to
> be in there, so I can't help you with the $timeworked assigment. Tell us
> a little
> bit more please.
>
> Rob
>
I reworked it and about 90% of it works.
#!/usr/bin/perl
use warnings;
use strict;
use lib '/usr/local/rt-3.6.3/lib';
use lib '/usr/local/rt-3.6.3/local/lib';
use RT;
use RT::Tickets;
use RT::Users;
RT::LoadConfig();
RT::Init();
my $tix = new RT::Tickets(RT::SystemUser);
$tix->FromSQL('Queue = "CustomerCare" OR Status = "resolved" OR Status = "open"');
my %timeworked;
while (my $ticket = $tix->Next) {
my $customer = $ticket->FirstCustomFieldValue('Environment');
unless ($customer) {warn "warning" . $ticket->id. "no environment"; next}
my %customer = ${customer};
my $transactions = $ticket->Transactions;
while (my $transaction = $transactions->Next) {
next unless ($transaction->TimeTaken);
my %env = $transaction->Creator;
my %env = ${env};
foreach my $cust (keys %customer) {
foreach my $user (keys %env) {
$env{$user} = $transaction->TimeTaken;
foreach my $time ( keys %{$env{$user}} ) {
$timeworked{$cust} = $env{$user}{$time};
}
}
}
foreach my $key (keys %env) {
print "Working on " . $ticket->id . " for $customer" .
" -> " . $key . "\n";
foreach my $subkey (keys %timeworked) {
print "Time worked for " . $subkey . " is " .
$timeworked{$subkey} . "\n";
}
}
}
}
What I get now is the following:
[Wed Mar 21 08:11:12 2007] [crit]: Can't use string ("5") as a HASH ref while
"strict refs" in use at ./user_timesheet_new.pl line 34.
(/usr/local/rt-3.6.3/lib/RT.pm:346)
Can't use string ("5") as a HASH ref while "strict refs" in use at
../user_timesheet_new.pl line 34.
I'm guessing "5" is a bit of data that is being pulled into the hash though I
don't know for certain. I have no way of telling since rolling back the change
I made to get to this point would leave me with nothing in that column anyway.
Mathew
| |
| Chas Owens 2007-03-21, 5:34 am |
| On 3/21/07, Mathew Snyder <theillien@yahoo.com> wrote:
snip
> my %customer = ${customer};
snip
Hashes cannot be created with only one value, they must always be in
pairs: key and value. If $customer has a type of HASH (you can put
print ref($customer), "\n";
in the code to check this) then you need to say
my %customer = %$customer;
to dereference the hashref.
snip
> my %env = $transaction->Creator;
> my %env = ${env};
snip
I have no idea why you are declaring %env twice. I also don't know
why you aren't getting an error due to the fact that $env is never
declared. I must assume this is not a direct copy of what you are
working with. If $transaction->Creator returns a list of key-value
pairs then that line is fine; if it returns a hashref instead then you
need to wrap it in %{} like this
my %env = %{$transaction->Creator};
snip
> $env{$user} = $transaction->TimeTaken;
snip
Again, unless $transaction->TimeTaken returns a list of key-value
pairs you have a problem here.
You should check your documentation to see what the return values of
these methods are.
| |
| Mathew Snyder 2007-03-21, 5:34 am |
| Chas Owens wrote:
> On 3/21/07, Mathew Snyder <theillien@yahoo.com> wrote:
> snip
> snip
>
> Hashes cannot be created with only one value, they must always be in
> pairs: key and value. If $customer has a type of HASH (you can put
>
> print ref($customer), "\n";
>
> in the code to check this) then you need to say
>
> my %customer = %$customer;
>
> to dereference the hashref
I'm under the impression that by assigning a single value to a hash it becomes
the key with the value being null.
..
>
> snip
> snip
>
> I have no idea why you are declaring %env twice. I also don't know
> why you aren't getting an error due to the fact that $env is never
> declared. I must assume this is not a direct copy of what you are
> working with. If $transaction->Creator returns a list of key-value
> pairs then that line is fine; if it returns a hashref instead then you
> need to wrap it in %{} like this
>
Actually, the double declaration was a mistake that I had seen immediately after
posting last time. I took it out but the error didn't go away.
> my %env = %{$transaction->Creator};
>
> snip
> snip
>
> Again, unless $transaction->TimeTaken returns a list of key-value
> pairs you have a problem here.
>
> You should check your documentation to see what the return values of
> these methods are.
>
I did as you said and dereferenced each of those methods. Now, instead of
getting "5" in the error, I'm getting "72". These numbers correspond to user
IDs. I don't know why it is telling me "Can't use string ("72") as a HASH ref
while "strict refs" in use at ./user_timesheet_new.pl line 27."
| |
| Rob Dixon 2007-03-21, 7:58 am |
| Mathew Snyder wrote:
>
> Rob Dixon wrote:
[snip old code][color=darkred]
>
> Essentially, this is a reporting script for our trouble ticket system. Each
> ticket has several transactions associated with it that actually make up
> the ticket. Some of those transactions are the addition of time spent on
> working on the ticket by its owner.
>
> What I am trying to do is create a hash of customers which will contain a
> hash of each user and the total time spent on the customer. First,
> creating the customer hash and then, for each customer, look at its tickets
> and keep a running total of time spent on the customer for each user.
>
> I reworked it and about 90% of it works.
>
> #!/usr/bin/perl
>
> use warnings;
> use strict;
> use lib '/usr/local/rt-3.6.3/lib';
> use lib '/usr/local/rt-3.6.3/local/lib';
> use RT;
> use RT::Tickets;
> use RT::Users;
>
> RT::LoadConfig();
> RT::Init();
>
> my $tix = new RT::Tickets(RT::SystemUser);
> $tix->FromSQL('Queue = "CustomerCare" OR Status = "resolved" OR Status = "open"');
>
> my %timeworked;
>
> while (my $ticket = $tix->Next) {
> my $customer = $ticket->FirstCustomFieldValue('Environment');
> unless ($customer) {warn "warning" . $ticket->id. "no environment"; next}
> my %customer = ${customer};
> my $transactions = $ticket->Transactions;
> while (my $transaction = $transactions->Next) {
> next unless ($transaction->TimeTaken);
>
> my %env = $transaction->Creator;
> my %env = ${env};
>
> foreach my $cust (keys %customer) {
> foreach my $user (keys %env) {
> $env{$user} = $transaction->TimeTaken;
> foreach my $time ( keys %{$env{$user}} ) {
> $timeworked{$cust} = $env{$user}{$time};
> }
> }
> }
>
> foreach my $key (keys %env) {
> print "Working on " . $ticket->id . " for $customer" . " -> " . $key . "\n";
> foreach my $subkey (keys %timeworked) {
> print "Time worked for " . $subkey . " is " . $timeworked{$subkey} . "\n";
> }
> }
> }
> }
>
> What I get now is the following:
> [Wed Mar 21 08:11:12 2007] [crit]: Can't use string ("5") as a HASH ref while "strict refs" in use at ./user_timesheet_new.pl line 34. (/usr/local/rt-3.6.3/lib/RT.pm:346)
> Can't use string ("5") as a HASH ref while "strict refs" in use at ./user_timesheet_new.pl line 34.
>
> I'm guessing "5" is a bit of data that is being pulled into the hash though
> I don't know for certain. I have no way of telling since rolling back the
> change I made to get to this point would leave me with nothing in that
> column anyway.
It's very unclear what you're trying to do, and what your RT package does. Let
me make some observations and guesses and you can tell me where I'm right or
wrong.
$tix is an iterator that will return a sequence of tickets through the Next
method.
$ticket is a data handle that will return an id, an Environment, and a
Transactions iterator. The environment appears to be a customer number.
$transaction is a RT handle that will return a TimeTaken and a Creator. The
creator appears to be a user identity.
What you want to generate is a hash of total time worked by each user across
all customers and tickets.
The code below may help. Clearly it is untested as I have no RT package or
database, but it is something we can discuss. Please let us know how close
this is to what you are aiming for.
HTH,
Rob
use warnings;
use strict;
use lib '/usr/local/rt-3.6.3/lib';
use lib '/usr/local/rt-3.6.3/local/lib';
use RT;
use RT::Tickets;
use RT::Users;
RT::LoadConfig();
RT::Init();
my $tix = new RT::Tickets($RT::SystemUser);
$tix->FromSQL('Queue = "CustomerCare" OR Status = "resolved" OR Status = "open"');
my %timeworked;
while (my $ticket = $tix->Next) {
my $id = $ticket->id;
my $customer = $ticket->FirstCustomFieldValue('Environment');
unless ($customer) {
warn "warning $id no environment";
next
}
my $transactions = $ticket->Transactions;
while (my $transaction = $transactions->Next) {
my $user = $transaction->Creator;
my $time = $transaction->TimeTaken;
$timeworked{$user} += $time;
}
}
foreach my $user (keys %timeworked) {
printf "%s -> %s\n", $user, $timeworked{$user};
}
| |
| Chas Owens 2007-03-21, 6:58 pm |
| On 3/21/07, Mathew Snyder <theillien@yahoo.com> wrote:
snip
> I'm under the impression that by assigning a single value to a hash it becomes
> the key with the value being null.
snip
Perl will let you do it, but it is not a good idea and almost
certainly is not what you want to do.
snip
> I did as you said and dereferenced each of those methods. Now, instead of
> getting "5" in the error, I'm getting "72". These numbers correspond to user
> IDs. I don't know why it is telling me "Can't use string ("72") as a HASH ref
> while "strict refs" in use at ./user_timesheet_new.pl line 27."
snip
Most likely because the methods you are using are not returning data
that should be stuffed into a hash in the way you are attempting. I
would suggest you go back and reread your documentation instead of
just trying to make it work they way you are doing it now.
| |
| Mathew Snyder 2007-03-23, 3:58 am |
| Rob Dixon wrote:
> It's very unclear what you're trying to do, and what your RT package
> does. Let
> me make some observations and guesses and you can tell me where I'm
> right or
> wrong.
>
> $tix is an iterator that will return a sequence of tickets through the Next
> method.
>
> $ticket is a data handle that will return an id, an Environment, and a
> Transactions iterator. The environment appears to be a customer number.
>
> $transaction is a RT handle that will return a TimeTaken and a Creator. The
> creator appears to be a user identity.
>
> What you want to generate is a hash of total time worked by each user
> across
> all customers and tickets.
>
> The code below may help. Clearly it is untested as I have no RT package or
> database, but it is something we can discuss. Please let us know how close
> this is to what you are aiming for.
>
> HTH,
>
> Rob
>
>
> use warnings;
> use strict;
>
> use lib '/usr/local/rt-3.6.3/lib';
> use lib '/usr/local/rt-3.6.3/local/lib';
> use RT;
> use RT::Tickets;
> use RT::Users;
>
> RT::LoadConfig();
> RT::Init();
>
> my $tix = new RT::Tickets($RT::SystemUser);
> $tix->FromSQL('Queue = "CustomerCare" OR Status = "resolved" OR Status =
> "open"');
>
> my %timeworked;
>
> while (my $ticket = $tix->Next) {
>
> my $id = $ticket->id;
> my $customer = $ticket->FirstCustomFieldValue('Environment');
>
> unless ($customer) {
> warn "warning $id no environment";
> next
> }
>
> my $transactions = $ticket->Transactions;
>
> while (my $transaction = $transactions->Next) {
>
> my $user = $transaction->Creator;
> my $time = $transaction->TimeTaken;
> $timeworked{$user} += $time;
> }
> }
>
> foreach my $user (keys %timeworked) {
> printf "%s -> %s\n", $user, $timeworked{$user};
> }
>
Rob,
You are correct in all of your assumptions above. Your code example spurred me
to get a bit further with my script. I now have this:
#!/usr/bin/perl
use warnings;
use strict;
use lib '/usr/local/rt-3.6.3/lib';
use lib '/usr/local/rt-3.6.3/local/lib';
use RT;
use RT::Tickets;
use RT::Users;
RT::LoadConfig();
RT::Init();
my $tix = new RT::Tickets(RT::SystemUser);
$tix->FromSQL('Queue = "CustomerCare" AND Status = "open" AND Created <
"2007-03-03"');
my %environment;
my %timeworked;
my $users = new RT::Users(RT::SystemUser);
$users->LimitToPrivileged;
while (my $ticket = $tix->Next) {
my $environment = $ticket->FirstCustomFieldValue('Environment');
unless ($environment) {
warn "warning" . $ticket->id. "no environment";
next
}
my $transactions = $ticket->Transactions;
while (my $transaction = $transactions->Next) {
next unless ($transaction->TimeTaken);
foreach my $user ($users->Next) {
if ($user = $transaction->Creator) {
$timeworked{$user} += $transaction->TimeTaken;
$environment{$environment} = $timeworked{$user};
}
}
}
}
foreach my $env (sort keys %environment) {
print "\n" . $env . "\n";
print "--------------------\n";
foreach my $user (sort keys %timeworked) {
print $user . " -> " . $timeworked{$user} . "\n";
}
}
This is getting closer to what I want. However, the %timeworked hash still
doesn't do what I'm looking for. Rather than only totalling up the time worked
on each customer for each user and then adding that to the customer environment
hash as $environment{$env}{$user} it is still iterating through every ticket and
transaction and adding that time to $timeworked{$user} which is then output for
each customer at the end. To clarify, each $environment{$env} has an identical
%timeworked hash printed with it. That %timeworked hash is a total for all time
for each user and not just the time for the customer.
I've tried so many different alterations but can't figure out how to get the
%timeworked hash populated the way I need and paired with the %environment hash
properly.
Your further assistance will be greatly appreciated.
Mathew
| |
| Chad Kemp 2007-03-23, 9:58 pm |
| Mathew,
try to test every condition going INTO the hash (or hashes) before
you actually assign a value to a key. as mentioned earlier, hashes must
be key/value pairs. the key will auto-vivify if a key is "new" but only
if a corresponding value accompanies it. when you assign values to all
of your hashes, check to see if that value is *defined*. when you try
to assign undefined values into a hash, you will get undesirable results.
you already know this, but just presenting it for the sake of
completeness... you need to ensure all of your KEYS are unique (unless
of course you want to overwrite the previous entry with the most
recent... last in, and all that :) ...
so now you have keys, and when you assign values to them, you need to
make sure it is defined, else store some arbitrary value in there that
you can test for later... like a scalar "empty" or something else that
is easily determined to NOT be useful data.
are you returning a hash from a method in another module? if so, try to
dereference it as soon as it is returned, storing it into a new lexical
hash and iterate through the lexical hash...
hope some of that helps.
i would include some code snips, but i am in the middle of a
construction project, and am pressed for time.
cheers
~CK
Mathew Snyder wrote:
> Rob Dixon wrote:
>
>
> Rob,
>
> You are correct in all of your assumptions above. Your code example spurred me
> to get a bit further with my script. I now have this:
>
> #!/usr/bin/perl
>
> use warnings;
> use strict;
> use lib '/usr/local/rt-3.6.3/lib';
> use lib '/usr/local/rt-3.6.3/local/lib';
> use RT;
> use RT::Tickets;
> use RT::Users;
>
> RT::LoadConfig();
> RT::Init();
>
> my $tix = new RT::Tickets(RT::SystemUser);
> $tix->FromSQL('Queue = "CustomerCare" AND Status = "open" AND Created <
> "2007-03-03"');
>
> my %environment;
> my %timeworked;
> my $users = new RT::Users(RT::SystemUser);
> $users->LimitToPrivileged;
>
> while (my $ticket = $tix->Next) {
> my $environment = $ticket->FirstCustomFieldValue('Environment');
>
> unless ($environment) {
> warn "warning" . $ticket->id. "no environment";
> next
> }
>
> my $transactions = $ticket->Transactions;
>
> while (my $transaction = $transactions->Next) {
> next unless ($transaction->TimeTaken);
>
> foreach my $user ($users->Next) {
> if ($user = $transaction->Creator) {
> $timeworked{$user} += $transaction->TimeTaken;
> $environment{$environment} = $timeworked{$user};
> }
> }
> }
> }
>
> foreach my $env (sort keys %environment) {
> print "\n" . $env . "\n";
> print "--------------------\n";
> foreach my $user (sort keys %timeworked) {
> print $user . " -> " . $timeworked{$user} . "\n";
> }
> }
>
> This is getting closer to what I want. However, the %timeworked hash still
> doesn't do what I'm looking for. Rather than only totalling up the time worked
> on each customer for each user and then adding that to the customer environment
> hash as $environment{$env}{$user} it is still iterating through every ticket and
> transaction and adding that time to $timeworked{$user} which is then output for
> each customer at the end. To clarify, each $environment{$env} has an identical
> %timeworked hash printed with it. That %timeworked hash is a total for all time
> for each user and not just the time for the customer.
>
> I've tried so many different alterations but can't figure out how to get the
> %timeworked hash populated the way I need and paired with the %environment hash
> properly.
>
> Your further assistance will be greatly appreciated.
>
> Mathew
>
>
| |
| Mathew Snyder 2007-03-25, 3:58 am |
| Chad Kemp wrote:
> Mathew,
>
> try to test every condition going INTO the hash (or hashes) before
> you actually assign a value to a key. as mentioned earlier, hashes must
> be key/value pairs. the key will auto-vivify if a key is "new" but only
> if a corresponding value accompanies it. when you assign values to all
> of your hashes, check to see if that value is *defined*. when you try
> to assign undefined values into a hash, you will get undesirable results.
> you already know this, but just presenting it for the sake of
> completeness... you need to ensure all of your KEYS are unique (unless
> of course you want to overwrite the previous entry with the most
> recent... last in, and all that :) ...
>
> so now you have keys, and when you assign values to them, you need to
> make sure it is defined, else store some arbitrary value in there that
> you can test for later... like a scalar "empty" or something else that
> is easily determined to NOT be useful data.
>
> are you returning a hash from a method in another module? if so, try to
> dereference it as soon as it is returned, storing it into a new lexical
> hash and iterate through the lexical hash...
>
This is what I think will have to be done. How do I go about that? Would I use
something like \%environment = $ticket->FirstCustomFieldValue('Environment')?
What I've been trying to do is place the object into a hash and then iterate
through it assigning 0 to each key.
[color=darkred]
> hope some of that helps.
>
> i would include some code snips, but i am in the middle of a
> construction project, and am pressed for time.
>
> cheers
>
> ~CK
>
>
Mathew
| |
| Chad Kemp 2007-03-30, 9:58 pm |
| Mathew Snyder wrote:
> Chad Kemp wrote:
>
> This is what I think will have to be done. How do I go about that? Would I use
> something like \%environment = $ticket->FirstCustomFieldValue('Environment')?
> What I've been trying to do is place the object into a hash and then iterate
> through it assigning 0 to each key.
>
>
>
> Mathew
>
>
Matthew,
* \%environment = $ticket->FirstCustomFieldValue('Environment')* is
actually CREATING a hash reference. and i think you are ending up with
a reference to a reference.
Try something like:
my $ref = $ticket->FirstCustomFieldValue('Environment');
my %hash = %$ref;
i have a program at work that i have custom packages defined and i am
passing it a Net::LDAP object (itself a hash)... performing some work,
and passing back a new hash... but what i actually get back is a hash
REF, so i have to dereference (as above) once i get it back... then i
can work on it.
|
|
|
|
|