Skip to content

Commit

Permalink
Released version 0.17
Browse files Browse the repository at this point in the history
  • Loading branch information
ingydotnet committed Sep 11, 2011
1 parent c47bc8a commit c30cf5c
Show file tree
Hide file tree
Showing 5 changed files with 77 additions and 20 deletions.
5 changes: 5 additions & 0 deletions Changes
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
---
version: 0.17
date: Sun Sep 11 03:24:17 CEST 2011
changes:
- Call BUILD sequence properly
---
version: 0.16
date: Sun Sep 11 01:31:30 CEST 2011
changes:
Expand Down
19 changes: 10 additions & 9 deletions README
Original file line number Diff line number Diff line change
Expand Up @@ -32,25 +32,26 @@ FEATURES
This is what you get. Nothing Mo.

"new" method
Mo provides a "new" object constructor. It will call the "BUILD"
method after creation if it "can".
Mo provides a "new" object constructor. You pass it a list of
name/value pairs and it returns a new object.

NOTE: Unlike other Moose modules, BUILD is not called in a chained
fashion. You would need to call "SUPER::BUILD" yourself, if you
needed that.
After creation, it will call the "BUILD" method for all its parents
and itself, if any of the classes have a "BUILD" method.

"extends"
Mo exports the "extends" keyword, to name your parent class. "Mo"
itself is your default parent class, of course.
itself is your default parent class, of course. You can have
multiple parent classes.

"has"
Mo exports a "has" keyword, to generate accessors.

These accessors support "get" and "set" operations and allows a
"default". That's it.

has 'name';
has 'name' => ( default => sub { 'Joe' } );
has 'name1';
has 'name2' => ( default => sub { 'Joe' } );
has 'name3' => ( builder => 'name_builder' );

"has" takes arguments after the name. Here is what it currently
supports:
Expand All @@ -72,7 +73,7 @@ FEATURES
Mo turns on "use strict" and "use warnings" for you.

Embeddable
Mo is tiny. It is currently 10 lines, <= 80 chars.
Mo is tiny. It is currently < 15 lines, < 80 chars each.

You could easily inline it in your code, if you wanted to.

Expand Down
9 changes: 6 additions & 3 deletions lib/Mo.pm
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
package Mo; require strict; require warnings; $Mo::VERSION = '0.16';
package Mo; require strict; require warnings; $Mo::VERSION = '0.17';
sub import {strict->import;warnings->import;my $p=caller;@{$p.'::ISA'}=$_[0];
*{$p.'::extends'} = sub {@{(caller).'::ISA'}=@_;eval "require $_" for @_};
*{$p.'::has'} = sub { my ($n, %a) = @_; my($d,$b)=@a{qw(default builder)};
*{(caller)."::$n"} = $d ? sub { $#_ ? ($_[0]{$n} = $_[1]) : (exists $_[0]{$n})
? $_[0]{$n} : ($_[0]{$n} = $d->($_[0])) } :
$b ? sub { $#_ ? ($_[0]{$n} = $_[1]) : (exists $_[0]{$n})
? $_[0]{$n} : ($_[0]{$n} = $_[0]->$b) }
: sub { $#_ ? $_[0]{$n} = $_[1] : $_[0]{$n} } };
} sub new {my $s=bless {@_[1..$#_]},$_[0]; $s->can('BUILD')&&$s->BUILD;$s}
: sub { $#_ ? $_[0]{$n} = $_[1] : $_[0]{$n} } }; }
sub _ { my ($a, $c) = @_; for my $p (@{$c."::ISA"}) { next if $p eq 'Mo';
unshift @$a, $p; _($a, $p); } @$a; }
sub new { my $c=shift; my$s=bless{@_},$c;
do{&{$_."::BUILD"}($s) if defined&{$_."::BUILD"}} for (_([$c],$c)); $s }
17 changes: 9 additions & 8 deletions lib/Mo.pod
Original file line number Diff line number Diff line change
Expand Up @@ -40,16 +40,16 @@ This is what you get. Nothing Mo.

=item C<new> method

Mo provides a C<new> object constructor. It will call the C<BUILD> method
after creation if it C<can>.
Mo provides a C<new> object constructor. You pass it a list of name/value
pairs and it returns a new object.

NOTE: Unlike other Moose modules, BUILD is not called in a chained fashion.
You would need to call C<SUPER::BUILD> yourself, if you needed that.
After creation, it will call the C<BUILD> method for all its parents and
itself, if any of the classes have a C<BUILD> method.

=item C<extends>

Mo exports the C<extends> keyword, to name your parent class. C<Mo> itself is
your default parent class, of course.
your default parent class, of course. You can have multiple parent classes.

=item C<has>

Expand All @@ -58,8 +58,9 @@ Mo exports a C<has> keyword, to generate accessors.
These accessors support C<get> and C<set> operations and allows a C<default>.
That's it.

has 'name';
has 'name' => ( default => sub { 'Joe' } );
has 'name1';
has 'name2' => ( default => sub { 'Joe' } );
has 'name3' => ( builder => 'name_builder' );

C<has> takes arguments after the name. Here is what it currently supports:

Expand Down Expand Up @@ -88,7 +89,7 @@ Mo turns on C<use strict> and C<use warnings> for you.

=item Embeddable

Mo is tiny. It is currently 10 lines, <= 80 chars.
Mo is tiny. It is currently < 15 lines, < 80 chars each.

You could easily inline it in your code, if you wanted to.

Expand Down
47 changes: 47 additions & 0 deletions t/build.t
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
use Test::More;

plan tests => 3;

$main::count = 1;

package Foo;
use Mo;
has 'foo' => (is => 'rw');
sub BUILD {
my $self = shift;
$self->foo($main::count++);
}

package Boo;
use Mo;
has 'boo' => (is => 'rw');
sub BUILD {
my $self = shift;
$self->boo($main::count++);
}

package Bar;
use Mo;
extends 'Foo', 'Boo';
has 'bar' => (is => 'rw');

package Baz;
use Mo;
extends 'Bar';
has 'baz' => (is => 'rw');
sub BUILD {
my $self = shift;
$self->baz($main::count++);
}

package Gorch;
use Mo;
extends 'Baz';
has 'gorch' => (is => 'rw');

package main;

my $g = Gorch->new;
is $g->boo, 1, 'boo builds first';
is $g->foo, 2, 'foo builds second';
is $g->baz, 3, 'baz builds third';

0 comments on commit c30cf5c

Please sign in to comment.