When reasonable, Object::InsideOut tries to do things the same as way as
Class::Std (e.g., :Private, :Restricted, :Cumulative and all the ":X-ify"
method attributes). However, as much as I admire the work that Damian Conway
put into developing Class::Std, I still found it to be only half-baked: Its
conventions were ad hoc, inconsistent and inflexible. Here are just a few
examples:
1. Class::Std lumps together accessor designation and ->new() argument
specification as part of the :Field designation in an ad hoc manner.
Object::InsideOUt logically separates the two because not all ->new()
arguments necessarily tie directly to a field.
2. Class::Std uses a mixture of attributes and specially-named methods.
Object::InsideOut is more consistent in using attributes throughout.
3. Class::Std does not allow control over the object ID. Object::InsideOut is
more flexible in allowing the developer to specify the object ID if needed.
Basically, I had to break a few eggs to make my omelet. However, I don't feel
that there is such a great diversity between the two. Consider the following
comparison (sorry, but I can't get it to format very well):
Class::Std Object::InsideOut
Class declaration use Class::Std use Object::InsideOut 'My::Class'
use base 'My::Class'
Object creation ->new({args}) ->new(args) or ->new({args})
Object initialization BUILD() :INIT
Object ID specification (N/A) :ID
Object ID ident($self) $$self
Object cloning (N/A) ->clone()
Object replicator (N/A) :REPLICATE
Object destruction DEMOLISH() :DESTROY
AUTOLOAD support AUTOMETHOD() :AUTOMETHOD
Field designation :ATTR :FIELD
Get accessor :ATTR(:get<name>) :FIELD('GET' => 'name')
Set accessor :ATTR(:set<name>) :FIELD('SET' => 'name')
Combined accessor (N/A) :FIELD('ACCESSOR' => 'name')
Restricted methods :RESTRICTED :RESTRICTED
Private methods :PRIVATE :PRIVATE
Cumulative methods :CUMULATIVE :CUMULATIVE(BOTTOM UP)
:CUMULATIVE(BASE FIRST) :CUMULATIVE
Chained methods (N/A) :CHAINED / :CHAINED(BOTTOM UP)
Overload methods :STRINGIFY :STRINGIFY
:NUMERIFY :NUMERIFY
:BOOLIFY :BOOLIFY
:ARRAYIFY :ARRAYIFY
:HASHIFY :HASHIFY
:GLOBIFY :GLOBIFY
:CODIFY :CODIFY
:SCALARIFY (N/A)
Object serialization ->_DUMP() ->dump()
Object loading (N/A) ->pump()
'require' not supported automatically supported
'threads' not supported supported
'threads::shared' not supported supported
Internal error handling Carp Exception::Class
Field initializer key :ATTR(:init_arg<key>)
my %init :InitArgs = (
'key' => {
'FIELD' => \@field
}
);
Field default :ATTR(:default<value>)
my %init :InitArgs = (
'key' => {
'DEFAULT' => value
}
);
Mandatory arguments N/A
my %init :InitArgs = (
'key' => {
'MANDATORY' => 1
}
);
Key pattern matching N/A
my %init :InitArgs = (
'key' => {
'REGEX' => qr/.../
}
);