flickr: philip66
Make your own Perl
with
Moop s
@friedo
Mike Friedman London Perl Workshop 2014
A brief history…
A brief history…
In the Beginning, Perl 5
was already extensible.
use Foo qw(bar);
use Foo qw(bar);
BEGIN {! require Foo;! Foo->import( ‘bar’ );!};
How does !
import!!
actually work?
sub import {! my $pkg = shift;! ...
a typical import sub
sub import {! my $pkg = shift;! my $callpkg = caller;! ...
a typical import sub
sub import {! my $pkg = shift;! my $callpkg = caller;! my @imports = @_;! ...
a typical import sub
sub import {! ... ! foreach ! my $sym(@imports) {! *{"${callpkg}::$sym"}! = *{"${pkg}::$sym"}
a typical import sub
(many details omitted.)
A brief history…
import is compile-time.
A brief history…
import is compile-time.
1. add functions. 2. pretend they’re keywords.
package Adder;!!
sub import { ... }!sub add2 { ! return shift + 2;!}
a pretend keyword
package Mine;!!
use Adder;!!
say add2 42;
a pretend keyword
A brief history…
Perl 5.2 !
Prototypes
Make fake keywords !
That behave like builtins
(kinda)
sub doblock(&@) { ! my $blk = shift;! return $blk->( @_ );!}!!
doblock { ! say $_ * $_ for @_;!} ( 1, 2, 3, 4, 5 );!
a prototype pretend keyword
sub doblock(&) { ... }!!
doblock { ! say "first";!}!!
say "second";
a prototype pretend keyword
sub doblock(&) { ... }!!
doblock { ! say "first";!}!!
say "second";
a prototype pretend keyword
# Fail :(
Prototype subs only work as expressions.
!
Not statements.
sub doblock($&) { ... }!!
doblock name { ! say "first";!}!!
a prototype pretend keyword
# Fail :(
a prototype pretend keyword
# We have to say:
!
!
doblock name => sub { ! say "first";!};!!
a prototype pretend keyword
# We have to say:
"&" prototypes are only magical if they're first.
A brief history…
Perl 5.8 !
Devel::Declare
The first real way to add !
new syntax.
use MooseX::Declare;!!
class Foo { ! method bar { ... }! ...!}!!
a parser magic keyword
Devel::Declare is complicated
Devel::Declare is complicated
•Declarators?
Devel::Declare is complicated
•Declarators?•Scope injectors?
Devel::Declare is complicated
•Declarators?•Scope injectors?•Method shadowing?
Devel::Declare is complicated
•Declarators?•Scope injectors?•Method shadowing?•WTF?
MooseX::Declare is big, slow, and difficult to
extend.
A brief history…
Perl 5.12 !
The keyword API
Real keyword interface in the
Perl core API.
package My::Keyword;!use Keyword::Simple;!!
sub import { ! Keyword::Simple::define( ! class => sub { ! munge_code( $$_[0] );! }!);!
a real custom keyword
So... !
what is !
M o o p s ?
use Moops;!role NamedThing {! has name => ! (is => "ro", isa => Str);!}! !class Person with NamedThing;!...
a Moops-defined class
So it's like MooseX::Declare
?
Not exactly.
Not exactly.
•Moo by default, but can use Moose
Not exactly.
•Moo by default, but can use Moose•Uses Keyword::Simple for new syntax.
Not exactly.
•Moo by default, but can use Moose•Uses Keyword::Simple for new syntax.•Uses Kavorka for functions/methods
Not exactly.
•Moo by default, but can use Moose•Uses Keyword::Simple for new syntax.•Uses Kavorka for functions/methods •Designed for easy extensibility
A brief history…
One year ago, !
I did this:
I like imports
I hate boilerplate
package MyApp::Setup;!use Import::Into;!!
use List::Util ();!use List::MoreUtils ();!use Scalar::Util ();!use Const::Fast ();!use Try::Tiny ();!use Data::Alias ();!use autodie ();!...
Custom setup class
!
!
sub import { ! my $callpkg = caller;! Scalar::Util->import::into(! $callpkg, 'blessed', 'refaddr'! );! List::Util->import::into(! $callpkg, 'reduce', 'all', ...! );! ...!}
Custom setup class
Works pretty great!
Unless I want to use custom syntax
use MooseX::Declare; !# (or Moops)!!
class MyApp::Thing { ! use MyApp::Setup;!}!!
# :/!Custom setup class
I have to use the Setup class from within
the right namespace.
What if the Setup class could also inject custom
syntax?
package MyApp::Setup;!use parent 'Moops';!sub import { ! my $pkg = shift;! my @imports = (! 'List::Util' => ['any'],! 'Scalar::Util' => ['blessed'],! 'experimental' => ['postderef']! ...! );!}
Moops-based setup class
sub import {! ...! $pkg->SUPER::import(! imports => \@imports! );!}!!
!
# :D
Moops-based setup class
Cool!
flickr: philip66
Questions
@friedo
Mike Friedman London Perl Workshop 2014
Top Related