I wanted to build an awesome place for people to discuss module specific issues, but I don't have any more time for this, and there are much better places to discuss Perl-related issues. I'd recommend asking your question on Stack Overflow or on Perl Monks.
If you are looking for a Perl tutorial or Perl-related news, I hope these links will serve you well.
Posted on 2008-06-24 13:56:29-07 by mgoldshteyn
Question about multi-field object tests in :Init
I would like to check if an object is in invariant form after all of the final initialization is performed in the :Init attributed subroutine. If the object is in an "improper" form, I would like to fail construction, just as field type validators throw an OIO::Args error. I realize that I can do this manually, but such functionality should probably be built in. For example, maybe some :Restricted function in Object::InsideOut itself that one could call from an :Init subroutine that would perform:
OIO::Args->die(...)
... with some supplied parameters.

Here is a somewhat contrived example that demonstrates the need and you can decide on the best approach:
sub _init :Init { # A car should not have any sort of wings as one of its parts # Note that this test involves two members of the class and could potentially # test base class members or functions on them, as well. if ($vehicle_type[$$self] eq 'car' && grep {/\Wwings\W/} @{$parts[$$self]}) { $self->fail_init( 'message' => 'A car should not have wings', 'Info' => 'A wings part was added to a vehicle of type car', ); # fail_init should do whatever it needs to and result in a die() # We never get to this point, because of the early exit due to fail_init } }

Thanks,

Michael Goldshteyn
Direct Responses: 8142 | Write a response
Posted on 2008-06-24 13:59:38-07 by mgoldshteyn in response to 8141
Re: Question about multi-field object tests in :Init
After thinking about this some more, perhaps we need a :PostInit function that does these sort of tests after all initialization is complete (well, at least for a particular class and its sub-classes) and causes construction to fail if an object is not in a class invariant form.

Thanks,

Michael Goldshteyn
Direct Responses: 8146 | Write a response
Posted on 2008-06-24 15:00:31-07 by jdhedden in response to 8142
Re: Question about multi-field object tests in :Init
As far as I can tell from what you've describe, the :Init subroutine is the appropriate place for such checks to be made. I also see no way to 'parametrize' the sort of checks you're suggesting. All of this sounds like class-specific checking that is appropriate for inclusion in an :Init subroutine.

If you can come up with a 'real' example where the existing model is inadequate, that might provide me with more ideas to chew on.
Direct Responses: 8148 | Write a response
Posted on 2008-06-24 15:45:21-07 by mgoldshteyn in response to 8146
Re: Question about multi-field object tests in :Init
Thanks for the speedy response. The only question that remains is, once an invariant test fails, what should be done to abort object initialization in the :Init attributed function, here after referred to as _init(), in a way similar to how it is aborted if for example the type of one of the passed in arguments is wrong. Or perhaps, in a way similar to how any unexpected key/value pairs passed to new() cause creation to fail. Basically, short of doing an explicit die() call in _init(), since I am not even certain if this:

1) Is appropriate...
2) Won't be caught by OIO guts, which call _init and result in undefined and/or unexpected behavior

... what should I do to abort object construction and trigger a die() like bounce back to the client caller of new() from _init().

Thanks for the comments,

Michael Goldshteyn
Direct Responses: 8154 | Write a response
Posted on 2008-06-24 17:02:21-07 by jdhedden in response to 8148
Re: Question about multi-field object tests in :Init
The proper way is to create an appropriate Exception::Class class that subclasses OIO:
package Foo; { use Object::InsideOut; use Exception::Class ( 'Foo::Err' => { 'isa' => 'OIO', 'description' => q/Bad 'Foo' thing happened/, } ); sub _init :Init { Foo::Err->die('message' => q/Your 'Foo' is bad/); } } package main; my $obj = Foo->new('arg' => 'bar');
See the DIAGNOSTICS section of the POD for how to trap such errors. And, of course, read about Exception::Class.
Direct Responses: 8157 | Write a response
Posted on 2008-06-24 18:16:34-07 by mgoldshteyn in response to 8154
Re: Question about multi-field object tests in :Init
Thank you very much for clarifying this for me. Now it is abundantly clear how an class invariant failure in _init() should be handled (i.e., through the use of a custom exception).

Michael Goldshteyn
Direct Responses: Write a response