Source Code Samples
package MyApp {
use Zydeco;
interface Iface::Named {
requires name;
}
class Animal {
with Iface::Named;
has name;
}
role Species ( Str $common_name, Str $binomial ) {
constant common_name = $common_name;
constant binomial = $binomial;
}
class Dog {
extends Animal;
with Species('dog', 'Canis familiaris');
method bark () {
say "woof!";
}
}
}
my $fido = MyApp->new_dog(name => "Fido");
print $fido->name, "\n" if $fido->does('MyApp::Iface::Named');
$fido->bark();
package MyApp {
use Zydeco;
class Person {
has name ( type => Str, required => true );
has gender ( type => Str );
factory new_man (Str $name) {
return $class->new(name => $name, gender => 'male');
}
factory new_woman (Str $name) {
return $class->new(name => $name, gender => 'female');
}
method greet (Person *friend, Str *greeting = "Hello") {
printf(
"%s, %s!\n",
$arg->greeting,
$arg->friend->name
);
}
}
}
my $alice = MyApp->new_woman("Alice");
my $bob = MyApp->new_man("Robert");
$alice->greet(friend => $bob);
package MyApp {
use Zydeco;
class Person {
has name! (type => Str);
has age (type => Int) = 0;
has status (
enum => ['alive', 'dead'],
handles => 1,
default => 'alive',
);
has children (
is => private,
default => sub { [] },
handles_via => 'Array',
handles => { add_child => 'push', all_children => 'all' },
);
}
}
my $bob = MyApp->new_person(name => "Robert", age => 30);
$bob->is_dead; # ==> false
$bob->add_child(
MyApp->new_person(name => "Eve")
);
package MyApp {
use Zydeco;
use DateTime;
class Person {
has name, spouse;
coerce from Str via from_string {
return $class->new(name => $_);
}
method marry (Person *partner, Object *date = DateTime->now) {
$self->spouse( $arg->partner );
$arg->partner->spouse( $self );
return $self;
}
}
}
use MyApp::Types qw( is_Person );
my $alice = MyApp->new_person(name => "Alice");
$alice->marry(partner => "Bob");
is_Person($alice->spouse); # ==> true
package MyApp {
use Zydeco;
class Person {
...;
before marry {
say "Speak now or forever hold your peace!";
}
after marry {
say "You may kiss the bride!";
}
}
}
package MyApp {
use Zydeco;
class JSON::Encoder {
multi method stringify (Undef $value) {
'null';
}
multi method stringify (ScalarRef[Bool] $value) {
$$value ? 'true' : 'false';
}
multi method stringify (Num $value) {
$value;
}
multi method stringify :alias(quote_str) (Str $value) {
sprintf(q<"%s">, quotemeta $value);
}
multi method stringify (ArrayRef $arr) {
sprintf(
q<[%s]>,
join(q<,>, map($self->stringify($_), @$arr))
);
}
multi method stringify (HashRef $hash) {
sprintf(
q<{%s}>,
join(
q<,>,
map sprintf(
q<%s:%s>,
$self->quote_str($_),
$self->stringify($hash->{$_}),
), sort keys %$hash
),
);
}
}
}
package MyApp {
use Zydeco;
use HTTP::Tiny;
class JSON::Uploader extends JSON::Encoder {
has ua (
is => lazy,
default => sub { HTTP::Tiny->new },
handles => {
'http_post' => 'post',
},
);
method req ($data) {
my %http_request = (
content => $self->stringify($data),
headers => { 'Content-Type' => 'application/json' },
);
return \%http_request;
}
method post_data ($data, Str $url) {
my $response = $self->http_post($url, $self->req($data));
$response->{success} or confess('HTTP error');
return $response->{content};
}
}
}
package MyApp {
use Zydeco;
use HTTP::Tiny;
class JSON::Uploader extends JSON::Encoder {
has ua (
is => private,
default => sub { HTTP::Tiny->new },
handles => [
\$http_post => 'post',
],
);
method $req ($data) {
my %http_request = (
content => $self->stringify($data),
headers => { 'Content-Type' => 'application/json' },
);
return \%http_request;
}
method post_data ($data, Str $url) {
my $response = $self->$http_post($url, $self->$req($data));
$response->{success} or confess('HTTP error');
return $response->{content};
}
}
}
package MyApp {
use Zydeco;
class Person {
has name = "Anonymous";
}
}
# Equivalent with Moose...
package MyApp {
sub new_person {
my $factory = shift;
"MyApp::Person"->new(@_);
}
}
package MyApp::Person {
use Moose;
use namespace::autoclean;
use constant FACTORY => "MyApp";
has name (is => "rw", default => "Anonymous");
}
package MyApp::Types {
use MooseX::Types -declare => ["Person"];
use namespace::autoclean;
class_type Person, { class => "MyApp::Person" };
}