Telephone +44(0)1524 64544
Email: info@shadowcat.co.uk

lpw-2009 - beginning-perl

Sat Dec 22 00:30:00 2012

Slides for the talk beginning-perl at lpw-2009

BEGINning
Perl

-

mst

-

perl(1)

-

Beginning
Perl

-

BEGINning
Perl

-

BEGIN
CHECK
INIT
END

-

BEGIN

-

lasts until
your main.pl
starts to run

-

use

-

  BEGIN {
    require Module;
    Module->import;
  }

-

  use strict;
  use warnings;

-

  $^H
  ${^WARNING_BITS}

-

  strict->import

-

affects
compilation
scope

-

  use Moose;

-

prototypes

-

  sub (&)

-

Try::Tiny

-

  try {
    ...
  } catch {
    ...
  };

-

Moose::Util::TypeConstraints

-

  type MyType
    => where { $_ =~ /mine/ };

-

sub binding

-

  foo()

-

binds at
compile
time

-

... so
you can
delete it

-

namespace::clean

-

  use Scalar::Util qw(blessed);
  use namespace::clean;

-

  delete ${Module::}{blessed};

-

CORE::GLOBAL

-

autodie

-

Fatal

-

  open my $fh, '<', $file
    or die "Argh: $!";

-

*CORE::GLOBAL::open

-

  use autodie;
  open my $fh, '<', $file;

-

use feature

-

  given ($foo) {
    when (/bar/) {
      ...
    }
    default {
      ...
    }
  }

-

  use 5.012; # strict!

-

source
filter

-

Switch.pm

-

ARGH

-

Smart::Comments

-

NOT
ARGH

-

 ### Debug output here

-

Devel::Declare

-

screw with
the parser

-

  method foo ($bar) {
    warn $bar;
  }

-

TryCatch

-

  try {
    ...
  } catch (FileException $e) {
    ...
  }

-

PerlX::MethodCallWithBlock

-

  $obj->iterate(3) {
    warn "hello! ".$_[0];
  };

-

autobox

-

screw with
the semantics

-

  [ 1, 2, 3 ]->each(sub {
    print "$_\n";
  });

-

  @stuff->grep(sub {
    $_ % 2
  });

-

accessor
building

-

  *{"${pkg}::${name}"}
    = sub { ... };

-

closures
eval

-

Moose

-

metaclass

-

metaclass
metamethod
metaattribute

-

  has foo => (
    is => 'rw',
    trigger => sub { ... }
  );

-

compiled
accessors

-

pay only
for what
you use

-

MooseX::Declare

-

  class MyClass is MyBaseClass
    with MyRole {

      method my_method (Str $arg) {

-

pluggable
design

-

CatalystX::Declare

-

  sub update :Chained('load_object')
    :PathPart('edit') :CaptureArgs(0) {

-

  controller MyController {

    action update under 'load_object' as 'edit' {

-

-

IPW

-

Web::Simple

-

prototypes
sub binding
CORE::GLOBAL

-

Mike
Whitaker

-

Devel::Declare

-

Dante's
Inferno

-

used to
being
satan

-

-

what if I
don't use
any of them?

-

not
using
code

-

but
first

-

let's shave
a yak

-

  foo(..., sub { ... }, ...);

-

how do I
cache that?

-

B::Deparse

-

closures

-

Data::Dump::Streamer

-

closures

-

record
refs

-

  local *Data::Dumper::_dump

-

Data::Visitor

-

  $save{refaddr($ref)}
    = '$input->[1]';

-

dump with
filter

-

  if (exists $save{refaddr($ref)}) {

-

  {
    string => "foo",
    code => undef
  }

-

  $structure->{code}
    = $input->[1];

-

  my $__captures = {
    "\$attr_trigger" => \undef,
    "\$attr_name" => \"foo"
  };

  # fixup code for external references
  $__captures->{"\$attr_trigger"} = \((\@_)->[6]);

-

  my $orig = MyModule->can('name');
  *MyModule::name = sub {
    <track refs in @_ here>
    $orig->(@_);
  };

-

  local *MyExporter::import = sub {
    $orig_import->(@_);
    <override imports here>
  };

-

  name('foo', sub { $bar }, 'baz');

-

  has foo => (
    is => 'rw',
    trigger => sub { ... }
  );

-

shaving
a moose

-

wrap Moose::import

-

warp Moose::import

-

track calls
to has

-

repeated
string eval
is SLOW

-

BUT

-

Class::MOP::Method::Generated
sub _eval_closure {

-

  my ($self, $lexicals, $code) = @_;

-

PadWalker
closed_over

-

save captures
save source

-

One1.txt
dump1.txt

-

make_immutable

-

  sub MooseX::Antlers::ImmutableHackFor
    ::NameOfClass::make_immutable {

-

  *meta = sub { $hack_class }

-

 *has = sub { ($replay_has{$_[0]}->(@_) }

-

there's
a pattern
here

-

  use MooseX::Antlers::StealImport
    Moose => {
      meta => sub { $hack_class },
      has => sub { ($replay_has{$_[0]}->(@_) }
    };

-

  no MooseX::Antlers::StealImport
    qw(Moose);

-

One2.txt
dump2.txt

-

metaclass

-

what if
we need
it later?

-

don't pay
for what you
don't use

-

__DATA__

-

  no warnings 'redefine';
  *One::meta = sub {
    my $meta_code = do {
      local $/; <One::DATA>
    };
    local $@;
    my $meta = eval $meta_code;
    die $@ if $@;
    $meta;
  };

-

dump3.txt

-

end
result?

-

Data::Dump::Streamer

-

  foreach my $method (qw(new DESTROY foo)) {
    is(
      $compiled_src{$method}, $orig_src{$method},
      "${method} restored ok"
    );
  }

-

character
identical

-

same for the
metaclass

-

One3.txt

-

  io('One.pmc') <
    MooseX::Antlers::Compiler
      ->load_with_compiler('One')
      ->compiled_source

-

net
gain?

-

  $ time perl t/lib/One.pm 
  real    0m1.213s
  $ time perl -Ilib One.pmc
  real    0m0.089s

-

questions?

-

  git://git.shadowcat.co.uk
       /gitmo
       /MooseX-Antlers.git

-

#moose
#moose-dev

-

thank
you