NAME
Zydeco::Lite - Zydeco without any magic
SYNOPSIS
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();
DESCRIPTION
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.
Syntax Examples
Apps
Apps:
app "MyApp" => sub {
# definition
};
Anonymous apps:
my $app = app sub {
# definition
};
Classes, Roles, Interfaces, and Abstract Classes
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
.
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 ];
};
Package Settings
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.
Attributes
Attributes:
has "myattr" => ( ... );
has [ "myattr1", "myattr2" ] => ( ... );
Private attributes:
has "myattr" => ( is => "private", ..., accessor => \(my $accessor) );
Methods
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.
Types
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
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
};
Utilities
Booleans:
my $truth = true;
my $truth = false;
Exceptions:
confess( 'Something bad happened' );
confess( 'Exceeded maximum (%d)', $max );
Formal Syntax
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 ) = @_;
...;
};
BUGS
Please report any bugs to http://rt.cpan.org/Dist/Display.html?Queue=MooX-Press.
SEE ALSO
AUTHOR
Toby Inkster <tobyink@cpan.org>.
COPYRIGHT AND LICENCE
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.
DISCLAIMER OF WARRANTIES
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.