Munich Perl Mongers Technical Meeting 05/2012
Daniel Bruder
use Moose;
has foo => (
is => 'rw',
isa => 'ArrayRef[Str]',
);
push %{ $self->foo }, @values;
use Moose;
has foo => (
is => 'rw',
isa => 'ArrayRef[Str]',
traits => [ 'Array' ],
);
use Moose;
has foo => (
is => 'rw',
isa => 'ArrayRef[Str]',
traits => [ 'Array' ],
handles => {
foo_push => 'push'
},
);
$self->foo_push(@values);
use Moose;
has foo => (
is => 'rw',
isa => 'ArrayRef[Str]',
traits => [ 'Array' ],
handles => {
foo_push => 'push',
foo_shift => 'shift',
},
);
$self->foo_push(@values);
my $str = $self->foo_shift;
use Moose;
has bar => (
is => 'rw',
isa => 'HashRef',
traits => [ 'Hash' ],
handles => {
bar_set => 'push',
bar_get => 'shift',
bar_defined => 'defined',
bar_exists => 'exists',
},
);
# Ok, this is contrived, but it gets the point across
my $bar = $self->bar_exists($value) ? $self->bar_get($value) : '';
You think Moose::Autobox is much cleaner, more intuitive, and generally, “beautiful”
use Moose;
use Moose::Autobox;
has foo => ( is => 'rw', isa => 'ArrayRef[Int]' );
$self->foo->push(1, 2, 3); # "fine"
$self->foo->push('a', 'b'); # "fine" too (but your validation is screwed)
$self->foo->shift; # "fine" too (too bad you didn't want your API
# to expose a shift method on foo...)
Because a Moose::Autobox-type-like approach won’t:
Traits are very well thought out, they let you apply method modifiers on them.
use MooseX::Declare;
class Baz {
# Suppose we haven't created a coercion to do this for us...
has foo => (
is => 'rw',
isa => 'ArrayRef[Str]', # suppose we only want uppercase strings here
traits => [ 'Array' ],
handles => {
foo_push => 'push',
foo_shift => 'shift',
},
);
around foo_push(Any $new?) {
return $self->$orig() unless $new;
return $self->$orig(map { uc } @$new);
}
# Now you can:
$self->foo_push(qw/foo bar baz quux/);
my $uc_str = $self->foo_shift; # ~~ 'FOO'
}
class Baz with MooseX::Getopt {
has foo => (
is => 'rw',
isa => 'Str',
traits => [ 'Getopt' ],
cmd_aliases => ['f', 'foo'],
default => 'foo',
);
}
package main;
print Baz->new_with_options->foo;
__END__
$ perl Baz.pm
# foo
$ Perl Baz.pm --foo=quux
# quux
$ Perl Baz.pm -f bar
# bar
class Download {
has ua => (
is => 'ro',
isa => 'WWW::Mechanize',
handles => ['get'],
);
}
$dl = Download->new;
$dl->get('www.mechanize.org');
# will call
$dl->ua->get('www.mechanize.org');
class Download {
has ua => (
is => 'ro',
isa => 'WWW::Mechanize',
handles => { download => 'get' }
);
}
$dl = Download->new;
$dl->download('www.mechanize.org');
# will call
$dl->ua->get('www.mechanize.org');
class Download {
has ua => (
is => 'ro',
isa => 'WWW::Mechanize',
handles => qr/g.*/,
);
}
$dl = Download->new;
$dl->get('www.mechanize.org');
# will call
$dl->ua->get('www.mechanize.org');
class Download {
has ua => (
is => 'ro',
isa => 'WWW::Mechanize',
handles => qr/g.*/,
);
}
$dl = Download->new;
$dl->get('www.mechanize.org');
# will call
$dl->ua->get('www.mechanize.org');
$dl->goofy('www.mechanize.org');
# will (try to) call
$dl->ua->goofy('www.mechanize.org');
class Download {
has ua => (
is => 'ro',
isa => 'WWW::Mechanize',
handles => qr/g.*/,
);
}
$dl = Download->new;
$dl->get('www.mechanize.org');
# will call
$dl->ua->get('www.mechanize.org');
$dl->goofy('www.mechanize.org');
# will (try to) call
$dl->ua->goofy('www.mechanize.org');
# (use with caution)
class Download {
has ua => (
is => 'ro',
isa => 'WWW::Mechanize',
handles => 'Downloadable', # a role name
);
}
The doc also says:
“Finally, you can also provide a sub reference to generate a mapping. You probably won’t need this version often (if ever). See the Moose docs for more details on exactly how this works” (never needed this)
has foo => (
is => 'rw',
isa => 'ArrayRef[Str]',
);
push %{ $self->foo }, @values;
has foo => (
is => 'rw',
isa => 'ArrayRef[Str]',
traits => [ 'Array' ],
handles => {
foo_push => 'push',
foo_shift => 'shift',
},
);
__ __
/\ \/\ \ Daniel Bruder
\_\ \ \ \____ IT-Services,
/'_` \ \ '__`\ Consulting &
/\ \L\ \ \ \L\ \ Training
\ \___,_\ \_,__/ daniel.bruder
\/__,_ /\/___/ @gmail.com