Zydeco::Lite - Zydeco without any magic
use strict; use warnings; use Zydeco::Lite; app "Local::MyApp" => sub { role "Greeting" => sub { method "greeting" => sub { return "Hello"; }; }; role generator "Location" => [ "Str" ] => sub { my ( $gen, $arg ) = @_; method "location" => sub { return $arg; }; }; class "Hello::World" => sub { with "Greeting"; with "Location" => [ "world" ]; method "do_it" => [] => sub { my $self = shift; print $self->greeting, " ", $self->location, "\n"; }; }; }; my $obj = "Local::MyApp""->new_hello_world; $obj->do_it();
Zydeco::Lite is a Zydeco-like module, but without using any parsing tricks. Zydeco requires Perl 5.14 or above, but Zydeco::Lite will run on any version of Perl since 5.8.8.
It's intended to be a happy medium between Zydeco and MooX::Press.
Apps:
app "MyApp" => sub { # definition };
Anonymous apps:
my $app = app sub { # definition };
Classes:
class "MyClass" => sub { # definition };
Anonymous classes:
my $class = class sub { # definition }; my $obj = $class->new();
Class generators:
class generator "MyGen" => sub { my ( $gen, @args ) = ( shift, @_ ); # definition }; my $class = $app->generate_mygen( @args ); my $obj = $class->new(); class generator "MyGen" => [ @signature ] => sub { my ( $gen, @args ) = ( shift, @_ ); # definition };
Anonymous class generators:
my $gen = class generator sub { my ( $gen, @args ) = ( shift, @_ ); # definition }; my $class = $gen->generate_package( @args ); my $obj = $class->new();
Roles, interfaces, and abstract classes work the same as classes, but use keywords role, interface, and abstract_class.
role
interface
abstract_class
Inheritance:
class "Base" => sub { }; class "Derived" => sub { extends "Base"; };
Inheritance using nested classes:
class "Base" => sub { ...; class "Derived" => sub { ...; }; };
Inheriting from a generated class:
class generator "Base" => sub { my ( $gen, @args ) = ( shift, @_ ); ...; }; class "Derived" => sub { extends "Base" => [ @args ]; };
Composition:
role "Named" => sub { requires "name"; }; class "Thing" => sub { with "Named"; has "name" => (); };
Composing an anonymous role:
class "Thing" => sub { with role sub { requires "name"; }; has "name" => (); };
Composing a generated role:
role generator "Thingy" => sub { my ( $gen, @args ) = ( shift, @_ ); ...; }; class "Derived" => sub { with "Thingy" => [ @args ]; };
Class version:
class "Foo" => sub { version "1.000"; }; class "Foo" => ( version => "1.0" ) => sub { ...; };
Class authority:
class "Foo" => sub { authority "cpan:TOBYINK"; }; class "Foo" => ( version => "1.0", authority => "cpan:TOBYINK" ) => sub { ...; };
Using non-Moo toolkits:
class "Foo" => sub { toolkit "Mouse"; }; class "Bat" => sub { toolkit "Moose" => ( "StrictConstructor" ); };
The version, authority, and toolkit keywords can be used within app, class, role, interface, or abstract_class definitions.
version
authority
toolkit
app
class
Attributes:
has "myattr" => ( ... ); has [ "myattr1", "myattr2" ] => ( ... );
Private attributes:
has "myattr" => ( is => "private", ..., accessor => \(my $accessor) );
Methods:
method "mymeth" => sub { my ( $self, @args ) = ( shift, @_ ); ...; };
Methods with positional signatures:
method "mymeth" => [ 'Num', 'Str' ] => sub { my ( $self, $age, $name ) = ( shift, @_ ); ...; };
Methods with named signatures:
method "mymeth" => [ age => 'Num', name => 'Str' ] => ( named => 1 ) => sub { my ( $self, $args ) = ( shift, @_ ); ...; };
Required methods in roles:
requires "method1", "method2"; requires "method3";
Method modifiers:
before "somemethod" => sub { my ( $self, @args ) = ( shift, @_ ); ...; }; after [ "method1", "method2"] => sub { my ( $self, @args ) = ( shift, @_ ); ...; }; around "another" => sub { my ( $next, $self, @args ) = ( shift, shift, @_ ); ...; $self->$next( @_ ); ...; };
Constants:
constant "ANSWER_TO_LIFE" => 42;
Overloading:
method "to_string" => sub { my $self = shift; ...; }; overload( q[""] => "to_string", fallback => 1, );
Factory methods:
factory "new_foo" => \"new"; factory "new_foo" => sub { my ( $factory, $class, @args ) = ( shift, shift, @_ ); return $class->new( @args ); };
Factory methods may include signatures like methods.
Indicate you want a class to have no factories:
factory();
The keywords multi_method and multi_factory exist for multimethods.
multi_method
multi_factory
Setting the type name for a class or role:
class "Foo::Bar" => sub { type_name "Foobar"; ...; };
Coercion:
class "Foo::Bar" => sub { method "from_arrayref" => sub { my ( $class, $aref ) = ( shift, @_ ); ...; }; coerce "ArrayRef" => "from_arrayref"; }; class "Foo::Bar" => sub { coerce "ArrayRef" => "from_arrayref" => sub { my ( $class, $aref ) = @_; ...; }; };
Hooks for classes:
begin { my ( $class ) = ( shift ); # Code that runs early during class definition }; end { my ( $class ) = ( shift ); # Code that runs late during class definition };
Hooks for roles:
begin { my ( $role ) = ( shift ); # Code that runs early during role definition }; end { my ( $role ) = ( shift ); # Code that runs late during role definition }; before_apply { my ( $role, $target ) = ( shift, shift ); # Code that runs before a role is applied to a package }; after_apply { my ( $role, $target ) = ( shift, shift ); # Code that runs after a role is applied to a package };
Booleans:
my $truth = true; my $truth = false;
Exceptions:
confess( 'Something bad happened' ); confess( 'Exceeded maximum (%d)', $max );
app( Optional[Str] $name, Hash %args, Optional[CodeRef] $definition, ); class( Optional[Str] $name, Hash %args, Optional[CodeRef] $definition, ); class generator( Optional[Str] $name, Optional[ArrayRef] $signature, Hash %args, Optional[CodeRef] $definition, ); role( Optional[Str] $name, Hash %args, Optional[CodeRef] $definition, ); role generator( Optional[Str] $name, Optional[ArrayRef] $signature, Hash %args, Optional[CodeRef] $definition, ); interface( Optional[Str] $name, Hash %args, Optional[CodeRef] $definition, ); interface generator( Optional[Str] $name, Optional[ArrayRef] $signature, Hash %args, Optional[CodeRef] $definition, ); abstract_class( Optional[Str] $name, Hash %args, Optional[CodeRef] $definition, ); abstract_class generator( Optional[Str] $name, Optional[ArrayRef] $signature, Hash %args, Optional[CodeRef] $definition, ); extends( List[Str|ArrayRef] @parents, ); with( List[Str|ArrayRef] @parents, ); method( Optional[Str] $name, Optional[ArrayRef] $signature, Hash %args, CodeRef $definition, ); factory( Str|ArrayRef $names, Optional[ArrayRef] $signature, Hash %args, CodeRef|ScalarRef $definition_or_via, ); constant( Str $name, Any $value, ); multi_method( Str $name, ArrayRef $signature, Hash %args, CodeRef $definition, ); multi_factory( Str $name, ArrayRef $signature, Hash %args, CodeRef $definition, ); before( Str|ArrayRef $names, Optional[ArrayRef] $signature, Hash %args, CodeRef $definition, ); after( Str|ArrayRef $names, Optional[ArrayRef] $signature, Hash %args, CodeRef $definition, ); around( Str|ArrayRef $names, Optional[ArrayRef] $signature, Hash %args, CodeRef $definition, ); has( Str|ArrayRef $names, Hash %spec, ); requires( List[Str] @names, ); confess( Str $template, List @args, ); toolkit( Str $toolkit, Optional[List] @imports, ); # TODO: coerce overload( Hash %args, ); version( Str $version, ); authority( Str $authority, ); type_name( Str $name, ); begin { ( $package ) = @_; ...; }; end { ( $package ) = @_; ...; }; before_apply { ( $role, $target ) = @_; ...; }; after_apply { ( $role, $target ) = @_; ...; };
Please report any bugs to http://rt.cpan.org/Dist/Display.html?Queue=MooX-Press.
Zydeco, MooX::Press.
Toby Inkster <tobyink@cpan.org>.
This software is copyright (c) 2020 by Toby Inkster.
This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.
THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
To install MooX::Press, copy and paste the appropriate command in to your terminal.
cpanm
cpanm MooX::Press
CPAN shell
perl -MCPAN -e shell install MooX::Press
For more information on module installation, please visit the detailed CPAN module installation guide.