Moose Lights up

Is may be the end of the errors Day here in the Moose-Pen.

I spen quite a bit of time mulling over the various options and possible solutions to the rater large mess I made yesterday with my recursive call to a eval.

I did manage to do a very long coded version where de-factored my code back to what it was when I starter earlier this week. A block of code for each 'undef' sistuation.

I wasn’t really satisfied with that as it was ugly, unmaintainable and I think very fragile once I got into more that two levels of recursion on my evals.

What to do?

Well I had a peek at the guts of 'AllErrors' MooseX and from the I could see that it was warping anything I was doing a new with its own 'around BUILDARGS' so that explain why I was getting three errors rather than just one. I also means that I have to do another shameful act;

package Database::Accessor::Types;
our $NEW;
our $LAST;
# ABSTRACT: A Types Role for Database::Accessor:
use Moose::Role;
with qw(Database::Accessor::Roles::AllErrors);
++ our $ALL_ERRORS = MooseX::Constructor::AllErrors::Error::Constructor->new({caller=>[]});

Create yet another global variable. I figured if I had a variable out side the scope of any of the recursive evaluation I cold just load the errors in there as I went along. If you look at it a global error like this does not really matter much as if it is created I have a error and it will soon be gone and if there is no error I can just undef it when I no longer need it.

To accomplish this I modified my '_create_instance' sub with a try catch;

sub _create_instance {
my ( $class, $ops,$caller,$raw ) = @_;
my $object;
if ($NEW) {
$LAST = $ops;
$object = $class->new( %{$ops} );
else {
try {
$object = $class->new( %{$ops});
} catch {
foreach my $error ($_->errors()){
if ($ALL_ERRORS->has_errors) {
my ( $package, $filename, $line, $subroutine ) = caller($caller);
die _one_error($ALL_ERRORS, $ops, $subroutine, $package, $filename, $line,$subroutine, $NEW,$raw );
$ALL_ERRORS = undef;

So what I do in the above is take any errors that are trapped in the catch and move them into the global $ALL_ERRORS and then once through the 'catch' I simple check for 'has_errors' and then die with what ever returns from the '_one_error' call

In the '_one_error' call the only change change I make was

-- die $die;
++ return $die;

and now when I do this;

$da->add_condition( {
leftx => {
name => 'last_name',
view => 'People'
operator => undef

I get this;

Database::Accessor Database::Accessor::add_condition Error:
The following Attribute is required: (conditions->left)
The following Attribute did not pass validation:
'conditions->operator' Constraint: The Operator 'undef', is not a valid Accessor Operator! Try one of '!=', '<', '<=', '<>', '=', '>', '>=', 'ALL', 'AND', 'ANY', 'BETWEEN', 'EXISTS', 'IN', 'IS NOT NULL', 'IS NULL', 'LIKE', 'NOT EXISTS', 'NOT IN', 'NOT LIKE', 'OR'
With constructor hash:
'predicates' => {
'operator' => undef,
'leftx' => {
'view' => 'People',
'name' => 'last_name'
at 42_new_validation.t line 93

very close to what I want;

An when I run this

$da->add_condition( undef);

I get;

Database::Accessor Database::Accessor::add_condition Error:
You cannot add 'undef' with Database::Accessor::add_condition at 42_new_validation.t line 86

So not doing to bad with this one. I now only have to fix up this

$da = Database::Accessor->new({
view => { name => 'People' },
elements => [ { name => 'first_name', }, { name => 'last_name', }, ],
conditions =>undef

as that is giving me bad results as well but at least I know why. I will have to make this little change;

if ($@) {
-- _one_error($@, $ops,'new',$package, $filename, $line, $subroutine,1);
++ die _one_error($@, $ops,'new',$package, $filename, $line, $subroutine,1);

in my 'around BUILDARGS' and now I get;

Database::Accessor new Error:
The following Attribute did not pass validation:
'Roles::Common->conditions' Constraint: Validation failed for 'ArrayRefofConditions' with value undef
With constructor hash:

close enough for late at night.


Leave a comment

About byterock

user-pic Long time Perl guy, a few CPAN mods allot of work on DBD::Oracle and a few YAPC presentations