NAME

Wurm::let - Local Evaluation Tether

SYNOPSIS

use Wurm qw(let);
use Data::Dumper;

# Re-implements the Hello, World app with let.
sub build_grub {
  my ($name) = @_;

  return Wurm::let->new
  ->gate(sub {
    my $meal = shift;
    $meal->{vent}{to} = ucfirst $name;
    push @{$meal->{grit}{path}}, $name. '/gate';
    return;
  })
  ->neck(sub {
    my $meal = shift;
    push @{$meal->{grit}{path}}, $name. '/neck';
    return;
  })
  # The same as ->body(get       => sub { })
  # The same as ->body([qw(get)] => sub { })
  ->get(sub {
    my $meal = shift;
    push @{$meal->{grit}{path}}, $name. '/body:get';
    return;
  })
  ->tail(sub {
    my $meal = shift;
    push @{$meal->{grit}{path}}, $name. '/tail';
    return wrap_it_up($meal);
  })
};

sub wrap_it_up {
  my $meal = shift;

  my $path = join ', ', @{$meal->{grit}{path}};

  my $text = '';
  $text .= "$meal->{mind}{intro} $meal->{vent}{to},\n";
  $text .= "This is the path I took: $path\n";
  $text .= "This is what is in the tube: $meal->{tube}\n";
  $text .= "This is what I've seen: $meal->{seen}\n";

  return Wurm::_200('text/plain', $text);
}

# How many methods are called before the assignment is made?
# This is the 'root' grub.
my $grub = build_grub('root')
  ->case(sub {
    my $meal = shift;
    $meal->{vent}{to}   = 'Nobody';
    $meal->{grit}{path} = [ ];
    return $meal;
  })
  ->pore(sub {
    my ($res, $meal) = @_;
    $res->[2][0] = $res->[2][0]
      . ($res->[0] == 200 ? '' : "\n")
      . 'PSGI env: '. Dumper($meal->{env})
    ;
    return $res;
  })
;

{
  # C<grub()> will make a new grub for us.
  # Or use what we give it.
  my $what = $grub->grub(wurm => build_grub('wurm'));

  # Grubs molt to become pretty butterflies.
  # If you believe nested hashes of anonymous sub-routines are
  # beautiful.  Or butterflies.

  # Tubes require molted grubs.
  $what->tube($_ => build_grub($_)->molt)
    for qw(foo bar baz);

  # I don't... better not to ask questions.  This looks nasty.
  $grub->grub($_ => $what->molt->{tube}{$_})
    for qw(foo baz);

  # qux is already molted inside $what.  eww.
  # I told you it was special.
  my $qux = $what->grub(qux => build_grub('qux'));
  $qux->gate(sub {
    my ($meal) = @_;
    $meal->{vent}{to} = 'Lord Qux';
    push @{$meal->{grit}{path}}, '*/gate';
    return wrap_it_up($meal);
  });
}

# Now turn the... uh... thing into an application.
my $app = Wurm::wrapp($grub->molt, {intro => 'Hello'});
$app

DESCRIPTION

Wurm::let is a utility module for helping create Wurm applications. It provides an easy-to-use OO interface for constructing folding rules without requiring applications to be OO-enabled themselves.

You can enable 'let' in two way:

use Wurm::let;

- or -

use Wurm qw(let);

METHODS

All methods (with the exception of grub) are meant for call chaining by returning the Wurm::let object. The grub method returns a new Wurm::let which can then be call-chained for setup.

new($bulk)

Creates a Wurm::let object for manipulating $bulk. If $bulk is not provided, it will be created as a HASH reference.

molt()

Returns the $bulk. Since folding rules are references, molt() can be called any time while still allowing changes to the Wurm::let. This allows you to either forward construct down-stream application logic and attach it in-whole to up-stream parts. Or you can create up-sream logic and generate down-stream pieces from it.

case($code)

Installs a case handler.

pore($code)

Installs a pore handler.

gate($code)

Installs a gate handler.

neck($code)

Installs a neck handler.

tail($code)

Installs a tail handler.

tube($name, $wurm)

Installs a tube handler tree with the key $name and a folding ruleset of $wurm. If $wurm is not provided it will be created for you. An easy way to chain application parts together is to create Wurm::let objects and molt() them into tube or use grub below.

my $stub = Wurm::let->new
  ->gate(sub { })
  ->post(sub { })
;

my $root = Wurm::let->new
  ->case(sub { })
  ->pore(sub { })
  ->tube(foo => $stub->molt)
  ->tube(bar => $stub->molt)
;
grub($name, $grub)

Installs a tube handler tree with the key $name and a folding ruleset of $grub. If $grub is not provided it will be created for you. If it is a HASH reference, it will be converted to a Wurm::let object which is returned.

my $root = Wurm::let->new;

# /mirror/ now contains the same folding rules as $root
$root->grub(mirror => $root)
     ->tail(sub { });          # changes /mirror/

# /foo/ will respond to gate and body/{get,post}
my $wurm = {gate => sub { ... }, ...};
my $grub = $root->grub(foo => $wurm);
$grub->body([qw(get post)] => sub { ... });
body($methods, $code)

Installs a body handler. $methods can either be a simple string or an ARRAY reference. If multiple methods are given, the same handler is installed for all of them.

get($code)

Installs a body handler for the 'GET' HTTP method.

head($code)

Installs a body handler for the 'HEAD' HTTP method.

post($code)

Installs a body handler for the 'POST' HTTP method.

put($code)

Installs a body handler for the 'PUT' HTTP method.

delete($code)

Installs a body handler for the 'DELETE' HTTP method.

trace($code)

Installs a body handler for the 'TRACE' HTTP method.

options($code)

Installs a body handler for the 'OPTIONS' HTTP method.

connect($code)

Installs a body handler for the 'CONNECT' HTTP method.

patch($code)

Installs a body handler for the 'PATCH' HTTP method.

SEE ALSO

Wurm

AUTHOR

jason hord <pravus@cpan.org>

LICENSE

This software is information. It is subject only to local laws of physics.