Then all your classes use code like:
package Your::Project::Widget; use Your::Project::Mite -all; has name => ( is => ro, isa => 'Str', ); has id => ( is => ro, isa => 'PositiveInt', ); signature_for warble => ( named => [ foo => 'Int', bar => 'ArrayRef', ], ); sub warble { my ( $self, $arg ) = @_; printf( "%s: %d\n", $self->name, $arg->foo ); return; } 1;
After writing or editing each class or role, you run the command "mite compile" and Mite will output a collection of compiled Perl classes which have no non-core dependencies (on Perl 5.14+. There are a couple of non-core dependencies on older versions of Perl.)
Attribute "isa" options are Type::Tiny type constraints expressed as strings. Mite looks them up during compilation using "dwim_type" from Type::Utils, and pre-loads Types::Standard, Types::Common::String, and Types::Common::Numeric for you.
The "signature_for" keyword is similar to the corresponding function in Type::Params. Again, note that types are expressed as strings and looked up using "dwim_type".
Any types which are inlineable should work. If using coercion, any coercions which are inlineable should work.
package Your::Project::Types; use Type::Library -extends => [ 'Types::Standard', 'Types::Common::Numeric' ]; __PACKAGE__->add_type( name => 'Widget', parent => InstanceOf['Your::Project::Widget'], )->coercion->add_type_coercions( HashRef, q{Your::Project::Widget->new($_)}, ); __PACKAGE__->make_immutable; 1;
Now if your classes load Your::Project::Types they'll suddenly have a dependency on Type::Library, so you don't get that nice zero-dependency feeling. But you can add this to your ".mite/config" file:
types: Your::Project::Types
Now Mite will know to load that type library at compile time, and will make those types available as stringy types everywhere.
has name => ( is => ro, isa => Str, );
One solution for that is Type::Library::Compiler.
Say you've created the custom type library above, you can use Type::Library::Compiler to compile it into a module called Your::Project::Types::Compiled, which just uses Exporter and doesn't rely on Type::Library or any other part of Type::Tiny.
Then your Widget class can use that:
package Your::Project::Widget; use Your::Project::Mite -all; use Your::Project::Types::Compiled -types; has name => ( is => ro, isa => Str, ); has id => ( is => ro, isa => PositiveInt, ); signature_for warble => ( named => [ foo => Int, bar => ArrayRef, ], ); sub warble { my ( $self, $arg ) = @_; printf( "%s: %d\n", $self->name, $arg->foo ); return; } 1;
The compiled type libraries are more limited than real type libraries. You can't, for example, do parameterized types with them. However, they still offer some cool features like:
Foo->check( $value ) # a few basic methods like this is_Foo( $value ) # boolean checks assert_Foo( $value ) # assertions which die Foo | Bar # unions!
This way you can write a project with object orientation, roles, method modifiers, type-checked attributes, type-checked signatures, and even coercion, with no non-core dependencies! (The tools like Mite and Type::Library::Compiler are only needed by the developer, not the end user.)
Including how to Type::Tiny in your object's "BUILD" method, and third-party shims between Type::Tiny and Class::Tiny.
This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.