Shadowcat Systems Limited

sufficiently advanced technology

Telephone 01524 842155
Email: info(at)shadowcat.co.uk

Digg! submit to reddit Delicious RSS Feed Readers

Ironman banner

This video was recorded at the Italian Perl Workshop in Pisa, Italy. The video contains many slides that are hard to read so these have been added in a scrollable box at the bottom of the page - each slide is seperated with a ----, you can move the slides in time to the presentation

The video source can be found at:
http://www.shadowcat.co.uk/archive/conference-video/ipw-2009/antiquated/video/-antiq-perl.flv

This text will be replaced

Antiquated Perl

----


Modern Perl?

----


Post Modern Perl

----


Enlightened Perl

----


everybody knows

----


Catalyst
Moose
DBIx::Class

----


Modern Perl?

----


perl5 v10

----


  given ($x) {
   when (3) {
  ...

----


~~

----


what's the opposite?

----


Old Perl?

----


if it works

----


Legacy Perl?

----


not interesting

----


Stupid Perl

----


*$&^*(^ FormMail.PL

----


Antiquated Perl

----


Antique

----


Old *and* beautiful

----


Simple Elegant

----


  $|++

----


  use IO::Handle;
  STDOUT->autoflush(1);

----


it's core.
it's fine.

----


but why think?

----


  select((select(FOO),$|++)[0])

----


  (select(FOO),$|++)
  ->
  ($old_selected_fh,$|)

----


  (select(FOO),$|++)[0]
  ->
  $old_select_fh

----


  select((select(FOO),$|++)[0])
  ->
  use IO::Handle;
  FOO->autoflush(1)

----


~~

----


  ~~@x

----


  ~(~(@x))

----


bitwise negation

----


so ...

----


  ~@x
  ->
  ~(scalar @x)

----


  ~~$number
  ->
  $number

----


  ~~@x
  ->
  scalar @x

----


  perl -MMoose -e'print ~~keys %INC'
  84

----


overload::constant

----


lets you affect parsing

----


numbers strings

----


q qq qr t s qw

----


i18n.pm

----


~~"$foo bar"
loc("_[0] bar", $foo)

----


for

----


  for ($foo) {
    /bar/ and ...

----


  for ($foo) {
    /bar/ and return do {
      <code here>
    }

----


  /foo/gc

----


  /\Gbar/gc

----


  sub parse {
    my ($self, $str) = @_;
    for ($str) {
      /match1/gc and return
        $self->_subparse_1($_)

----


  sub _subparse_1 {
    my ($self) = @_;
    for ($_[1]) {
      /\Gsubmatch1/gc ...

----


prototypes

----


  sub foo (&) {

----


  foo {
    ...
  };

----


  prototype \&foo

----


typeglobs

----


  *{"${package}::${name}"}
    = sub { ... }

----


  local

----


  local $_

----


  local *Carp::croak
    = \&Carp::confess;

----


  do {
    local (@ARGV, $/) = $file;
    <>
  }

----


strict and warnings

----


  strict->import

----


affects compilation scope

----


  sub strict_and_warnings::import {
    strict->import;
    warnings->import;
  }

----


  use strict_and_warnings;

----


$^H
%^H

----


  $^H |= 0x120000;
  $^H{'foo'}
    = bless($foo, 'My::Foo');

----


  sub My::Foo::DESTROY {

----


  delete ${$package}{myimport}

----


B::Hooks::EndOfScope

----


tie

----


  tie $var, 'Foo';

----


  sub FETCH
  sub STORE

----


Scalar 
Array 
Hash
Handle

----


now ...

----


mst: destruction testing technology since March 1983

----


3 days old

----


2 weeks early

----


incubator

----


glass box 
plastic tray
heater

----


design flaw

----


BANG

----


so ...

----


interesting fact

----


prototypes only warn
when parsed

----


error when compiled

----


so ...

----


  dispatch [
    sub (GET + /) { ... },
    sub (GET + /user/*) { ... }
  ];

----


  foreach my $sub (@$dispatch) {
    my $proto = prototype $sub;
    $parser->parse($proto);
    ...

----


  PARSE: { do {
    push @match, $self->_parse_spec_section($spec)
      or $self->_blam("Unable to work out what the next section is");
    last PARSE if (pos == length);
    /\G\+/gc or $self->_blam('Spec sections must be separated by +');
  } until (pos == length) };

----


  sub _blam {
    my ($self, $error) = @_;
    my $hat = (' ' x pos).'^';
    die "Error parsing dispatch specification: ${error}\n
  ${_}
  ${hat} here\n";
  }

----


  Error parsing ...
  GET+/foo
     ^ here

----


  sub (GET + /user/*) {
   my ($self, $user) = @_;

----


I hate fetching
 $self

----


  *{"${app}::self"}
    = \${"${app}::self"};

----


use vars

----


  sub _run_with_self {
    my ($self, $run, @args) = @_;
    my $class = ref($self);
    no strict 'refs';
    local *{"${class}::self"} = \$self;
    $self->$run(@args);
  }

----


HTML output

----


templates

----


HTML is NOT TEXT

----


  <div>,
    $text,
  </div>;

----


<div>

----


<$fh>

----


  tie *{"${app}::${name}"},
    'XML::Tags::TIEHANDLE',
    "<${name}>";

----


  sub TIEHANDLE { my $str = $_[1]; bless \$str, $_[0] }
  sub READLINE { ${$_[0]} }

----


  sub DESTROY {
    my ($into, @names) = @$_[0];
    no strict 'refs';
    delete ${$into}{$_}
      for @names;
  }

----


</div>

----


glob('/div');

----


  *CORE::GLOBAL::glob
    = sub { ... };

----


  delete
    ${CORE::GLOBAL::}{glob};

----


  sub foo {
    use XML::Tags qw(div);
    <div>, "foo!", </div>;
  }

----


what about interpolation

----


  my $stuff = 'foo"bar';
  <a href="$stuff">

----


hmm ...

----


overload::constant!

----


  glob('a href="'.$stuff.'"');

----


  glob(
    bless(\'a href="', 'MagicTag')
    .$stuff
    .bless(\'"', 'MagicTag')
  )

----


  use overload
    '.' => 'concat';

   sub concat {

----


hooking it up

----


  sub (.html) {
    filter_response {
      $self->render_html($_[1])
    }
  }

----


  bless(
    $_[1],
    'Web::Simple::ResponseFilter'
  );

----


  if ($self->_is_response_filter($result)) {
    return $self->_run_with_self(
      $result,
      $self->_run_dispatch_for($new_env, \@disp)
    );
  }

----


and the result?

----


 goto &demo;

----


questions?

----


thank you

----