Home > Archive > PERL Beginners > October 2006 > Error Handling
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]
|
|
| Jen Spinney 2006-10-22, 7:57 am |
| Hello all.
I have a subroutine that I want to send a bunch of arguments/parameters to.
I find it easier to pass a hash ref to this sub instead of comma separated
arguments because then I don't have to remember the order, and the intention
of each argument is clearer.
Within this sub, I want to check if the hash ref it was passed is complete
(ie it has all the keys it will need).
So far it looks like this (bare bones version):
use strict;
use warnings;
mySub ({
color => 'blue',
phone => '555-5555',
url => 'http://www.google.com',
someKey => 'Some Value'
});
sub mySub
{
my $hash_ref = shift;
if (!exists $hash_ref->{color} ||
!exists $hash_ref->{phone} ||
!exists $hash_ref->{url} ||
!exists $hash_ref->{someKey})
{
die "mySub not provided complete hash ref";
}
#Do stuff
}
__END__
First of all, is there a nicer/easier/prettier way to check for the
existance of all those hash keys?
But my real question is how to make it die with better information. Right
now, if I comment out one of those key/value pairs in the subroutine call,
my script will die with the message
"mySub not provided complete hash ref at line 20". But, the actual
infraction -- the thing I really care about and want to hunt down -- is at
the subroutine call.
Is there a way for mySub to know what line it was called from?
If not, should I go about this using eval blocks and throwing exceptions?
I'm looking for pointers on better perl coding style, so anything you can
throw at me is appreciated (like -- should I not even been sending a hash
ref? Should I use something else?).
Thanks for any help!
- Jen
| |
| FishMonger 2006-10-22, 11:38 am |
| quote: Originally posted by Jen Spinney
Hello all.
I have a subroutine that I want to send a bunch of arguments/parameters to.
I find it easier to pass a hash ref to this sub instead of comma separated
arguments because then I don't have to remember the order, and the intention
of each argument is clearer.
Within this sub, I want to check if the hash ref it was passed is complete
(ie it has all the keys it will need).
So far it looks like this (bare bones version):
use strict;
use warnings;
mySub ({
color => 'blue',
phone => '555-5555',
url => 'http://www.google.com',
someKey => 'Some Value'
});
sub mySub
{
my $hash_ref = shift;
if (!exists $hash_ref->{color} ||
!exists $hash_ref->{phone} ||
!exists $hash_ref->{url} ||
!exists $hash_ref->{someKey})
{
die "mySub not provided complete hash ref";
}
#Do stuff
}
__END__
First of all, is there a nicer/easier/prettier way to check for the
existance of all those hash keys?
But my real question is how to make it die with better information. Right
now, if I comment out one of those key/value pairs in the subroutine call,
my script will die with the message
"mySub not provided complete hash ref at line 20". But, the actual
infraction -- the thing I really care about and want to hunt down -- is at
the subroutine call.
Is there a way for mySub to know what line it was called from?
If not, should I go about this using eval blocks and throwing exceptions?
I'm looking for pointers on better perl coding style, so anything you can
throw at me is appreciated (like -- should I not even been sending a hash
ref? Should I use something else?).
Thanks for any help!
- Jen
Here's one approach:
code: sub mySub
{
my ($pkg, $file, $line) = caller;
my $hash_ref = shift;
my @missing;
foreach my $key (qw[color phone url someKey])
{
push @missing, $key if !exists $hash_ref->{$key};
}
if (@missing)
{
die "mySub called at line $line is missing required hash key(s):".join ',', @missing;
}
#do stuff
}
| |
| Tom Phoenix 2006-10-22, 9:56 pm |
| On 10/22/06, Jen Spinney <jen.spinney@gmail.com> wrote:
> if (!exists $hash_ref->{color} ||
> !exists $hash_ref->{phone} ||
> !exists $hash_ref->{url} ||
> !exists $hash_ref->{someKey})
> {
> die "mySub not provided complete hash ref";
> }
Maybe this (untested)?
die "mySub not provided complete hash ref"
if grep !(exists $hash_ref->{$_}), qw/ color phone url someKey /;
> But my real question is how to make it die with better information. Right
> now, if I comment out one of those key/value pairs in the subroutine call,
> my script will die with the message
> "mySub not provided complete hash ref at line 20". But, the actual
> infraction -- the thing I really care about and want to hunt down -- is at
> the subroutine call.
You probably want croak, instead of die; see the Carp module.
> I'm looking for pointers on better perl coding style, so anything you can
> throw at me is appreciated (like -- should I not even been sending a hash
> ref? Should I use something else?).
A lot depends upon your circumstances; the way you're doing it isn't
necessarily unreasonable. In fact, your method may be best if the sub
is called frequently with many arguments unchanged from the previous
call.
You might want to see what modules on CPAN use similar techniques, and how.
Hope this helps!
--Tom Phoenix
Stonehenge Perl Training
| |
| Jen Spinney 2006-10-22, 9:56 pm |
| On 10/22/06, Tom Phoenix <tom@stonehenge.com> wrote:
>
> On 10/22/06, Jen Spinney <jen.spinney@gmail.com> wrote:
>
>
> Maybe this (untested)?
>
> die "mySub not provided complete hash ref"
> if grep !(exists $hash_ref->{$_}), qw/ color phone url someKey /;
>
> information. Right
> call,
> at
>
> You probably want croak, instead of die; see the Carp module.
>
> can
> hash
>
> A lot depends upon your circumstances; the way you're doing it isn't
> necessarily unreasonable. In fact, your method may be best if the sub
> is called frequently with many arguments unchanged from the previous
> call.
>
> You might want to see what modules on CPAN use similar techniques, and
> how.
>
> Hope this helps!
>
> --Tom Phoenix
> Stonehenge Perl Training
Thanks! croak is just what I needed. And the grepping works perfectly as
well.
Nice job on the O'Reilly book as well.
Merci
- Jen
|
|
|
|
|