--- /dev/null
+package Class::Tiny;
+
+use strictures 1;
+use Class::Tiny::_Utils;
+
+sub import {
+ my $target = caller;
+ *{_getglob("${target}::extends")} = sub {
+ *{_getglob("${target}::ISA")} = \@_;
+ };
+ *{_getglob("${target}::with")} = sub {
+ require Role::Tiny;
+ die "Only one role supported at a time by with" if @_ > 1;
+ Role::Tiny->apply_role_to_package($_[0], $target);
+ };
+ foreach my $type (qw(before after around)) {
+ *{_getglob "${target}::${type}"} = sub {
+ _install_modifier($target, $type, @_);
+ };
+ }
+ {
+ no strict 'refs';
+ @{"${target}::ISA"} = do {
+ require Class::Tiny::Object; ('Class::Tiny::Object');
+ } unless @{"${target}::ISA"};
+ }
+}
+
+1;
--- /dev/null
+package Class::Tiny::Object;
+
+use strictures 1;
+
+sub new {
+ my $class = shift;
+ bless({ @_ }, $class);
+}
+
+sub does {
+ require Role::Tiny;
+ { no warnings 'redefine'; *does = \&Role::Tiny::does_role }
+ goto &Role::Tiny::does_role;
+}
+
+1;
--- /dev/null
+package Class::Tiny::_Utils;
+
+use strictures 1;
+use base qw(Exporter);
+
+our @EXPORT = qw(_getglob _install_modifier);
+
+sub _getglob { no strict 'refs'; \*{$_[0]} }
+
+sub _install_modifier {
+ require Class::Method::Modifiers;
+ my ($into, $type, $name, $code) = @_;
+ my $ref = ref(my $to_modify = $into->can($name));
+ if ($ref && $ref =~ /Sub::Defer::Deferred/) {
+ require Sub::Defer; undefer($to_modify);
+ }
+ Class::Method::Modifiers::install_modifier(@_);
+}
+
+1;
package Role::Tiny;
use strictures 1;
-use Class::Method::Modifiers ();
+use Class::Tiny::_Utils;
our %INFO;
our %APPLIED_TO;
-sub _getglob { no strict 'refs'; \*{$_[0]} }
-
sub import {
my $target = caller;
# get symbol table reference
}
foreach my $modifier (@{$info->{modifiers}||[]}) {
- Class::Method::Modifiers::install_modifier($to, @{$modifier});
+ _install_modifier($to, @{$modifier});
}
# only add does() method to classes and only if they don't have one
use strictures 1;
use base qw(Exporter);
+use Class::Tiny::_Utils;
our @EXPORT = qw(defer undefer);
our %DEFERRED;
-sub _getglob { no strict 'refs'; \*{$_[0]} }
-
sub undefer {
my ($deferred) = @_;
my ($target, $maker, $undeferred_ref) = @{
--- /dev/null
+use strictures 1;
+use Test::More;
+
+{
+ package MyClass0;
+
+ BEGIN { our @ISA = 'ZeroZero' }
+
+ use Class::Tiny;
+}
+
+BEGIN {
+ is(
+ $INC{'Class/Tiny/Object.pm'}, undef,
+ 'Object.pm not loaded if not required'
+ );
+}
+
+{
+ package MyClass1;
+
+ use Class::Tiny;
+}
+
+is_deeply(
+ [ @MyClass1::ISA ], [ 'Class::Tiny::Object' ], 'superclass defaulted'
+);
+
+{
+ package MyClass2;
+
+ use base qw(MyClass1);
+ use Class::Tiny;
+}
+
+is_deeply(
+ [ @MyClass2::ISA ], [ 'MyClass1' ], 'prior superclass left alone'
+);
+
+{
+ package MyClass3;
+
+ use Class::Tiny;
+
+ extends 'MyClass2';
+}
+
+is_deeply(
+ [ @MyClass3::ISA ], [ 'MyClass2' ], 'extends sets superclass'
+);
+
+{
+ package MyClass4;
+
+ use Class::Tiny;
+
+ extends 'WhatTheFlyingFornication';
+
+ extends qw(MyClass2 MyClass3);
+}
+
+is_deeply(
+ [ @MyClass4::ISA ], [ qw(MyClass2 MyClass3) ], 'extends overwrites'
+);
+
+{
+ package MyClass5;
+
+ use Class::Tiny;
+
+ sub foo { 'foo' }
+
+ around foo => sub { my $orig = shift; $orig->(@_).' with around' };
+}
+
+is(MyClass5->foo, 'foo with around', 'method modifier');
+
+done_testing;