Here is the current method:
sub new {
my ($package, $message) = (shift, shift);
my %params = @_;
return bless { message => $message, %params }, $package;
}
This method returns basically an error string , but I want to modify it so it will also be able to take my new error structure and return the string from the error hash. I can't get my head around how to use bless. The %params accepts runtime parameter but they can be ignored for now I would think.
Here is the error structure:
# this constant is an example of an error library (just included 1 error for example)
use constant {
CABLING_ERROR => {
errorCode => 561,
message => "Cabling incorrect to device in server A4r, contact DCT ",
tt => { template => 'cable'},
fatal => 1,
link =>'http://www.error-fix.com/cabling
},
};
I just started throwing down some code to start , it's a poor attempt but this is how I began modifying the new() method:
sub new {
my ($package, $message) = (shift, shift);
# defining new error hash
my $hash($errorCode, $message, $tt, $fatal, $link) = (shift, shift, shift, shift);
my %params = @_;
if(exists $hash->{errorCode}) {
return bless { errorCode => $errorCode, message => $message, tt => $tt, fatal => $fatal, link => $link}, %params;
}
else {
return bless { message => $message, %params }, $package;
}
}
My understanding of bless is that it makes object of hash refs. The errors are held in the constant list. Here is an example of how it is to be executed:
if(!device_model) {
die ARC::Builder::Error->new(CABLING_ERROR);
}
UPDATE: I have been trying to unit test your solution @simbabque but I keep getting an empty string as a return value instead of the error message string. Maybe it's my test that it isn't set up correctly? Below is an example of the test I created:
my $error = CABLING_ERROR;
my $exp_out_A = ($error->{message});
my $error_in = new($error);
diag($error_in);
is($error_in, $exp_out_A, 'Correct message output');
What you actually want is your constructor to distinguish between if it was called with a message string, or with a hash of a known form that contains the message string. Basically you want to coerce the message attribute.
sub new {
my ($package, $thing) = (shift, shift);
my %params = @_;
if (ref $thing eq 'HASH') {
return bless { message => $thing->{message}, %params }, $package;
}
return bless { message => $thing, %params }, $package;
}
That's it. Just check the ref
of the param you are getting. If it's a hash reference, it will be 'HASH'
. If it's a simple string, it will be undef
.
In case you want to build up more %params
automatically from your hash reference, that would look something like this.
return bless { message => $thing->{message}, foo => $thing->{foo}, %params }, $package;