summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorJesse Luehrs <doy@tozt.net>2011-02-20 02:04:52 -0600
committerJesse Luehrs <doy@tozt.net>2011-02-20 02:04:52 -0600
commit8ad579f26a1c74d5685491df55b57e694e54e087 (patch)
treede3c03114a1932c1ddbb4a72ae5c34c5ceaf19f3 /lib
parenta0cc11a5f9b60226a07054d6041cc45b4ea2221a (diff)
downloadbread-board-declare-8ad579f26a1c74d5685491df55b57e694e54e087.tar.gz
bread-board-declare-8ad579f26a1c74d5685491df55b57e694e54e087.zip
initial implementation
Diffstat (limited to 'lib')
-rw-r--r--lib/MooseX/Bread/Board.pm25
-rw-r--r--lib/MooseX/Bread/Board/BlockInjection.pm10
-rw-r--r--lib/MooseX/Bread/Board/ConstructorInjection.pm10
-rw-r--r--lib/MooseX/Bread/Board/Literal.pm10
-rw-r--r--lib/MooseX/Bread/Board/Meta/Role/Attribute.pm109
-rw-r--r--lib/MooseX/Bread/Board/Meta/Role/Class.pm19
-rw-r--r--lib/MooseX/Bread/Board/Role/Object.pm27
-rw-r--r--lib/MooseX/Bread/Board/Role/Service.pm32
8 files changed, 242 insertions, 0 deletions
diff --git a/lib/MooseX/Bread/Board.pm b/lib/MooseX/Bread/Board.pm
index e69de29..f40797e 100644
--- a/lib/MooseX/Bread/Board.pm
+++ b/lib/MooseX/Bread/Board.pm
@@ -0,0 +1,25 @@
+package MooseX::Bread::Board;
+use Moose::Exporter;
+
+my (undef, undef, $init_meta) = Moose::Exporter->build_import_methods(
+ install => ['import', 'unimport'],
+ class_metaroles => {
+ attribute => ['MooseX::Bread::Board::Meta::Role::Attribute'],
+ class => ['MooseX::Bread::Board::Meta::Role::Class'],
+ },
+ base_class_roles => ['MooseX::Bread::Board::Role::Object'],
+);
+
+sub init_meta {
+ my $package = shift;
+ my %options = @_;
+ if (my $meta = Class::MOP::class_of($options{for_class})) {
+ my @supers = $meta->superclasses;
+ $meta->superclasses('Bread::Board::Container')
+ if @supers == 1 && $supers[0] eq 'Moose::Object';
+ }
+ $package->$init_meta(%options);
+}
+
+
+1;
diff --git a/lib/MooseX/Bread/Board/BlockInjection.pm b/lib/MooseX/Bread/Board/BlockInjection.pm
new file mode 100644
index 0000000..e1dca1e
--- /dev/null
+++ b/lib/MooseX/Bread/Board/BlockInjection.pm
@@ -0,0 +1,10 @@
+package MooseX::Bread::Board::BlockInjection;
+use Moose;
+
+extends 'Bread::Board::BlockInjection';
+with 'MooseX::Bread::Board::Role::Service';
+
+__PACKAGE__->meta->make_immutable;
+no Moose;
+
+1;
diff --git a/lib/MooseX/Bread/Board/ConstructorInjection.pm b/lib/MooseX/Bread/Board/ConstructorInjection.pm
new file mode 100644
index 0000000..f3b345b
--- /dev/null
+++ b/lib/MooseX/Bread/Board/ConstructorInjection.pm
@@ -0,0 +1,10 @@
+package MooseX::Bread::Board::ConstructorInjection;
+use Moose;
+
+extends 'Bread::Board::ConstructorInjection';
+with 'MooseX::Bread::Board::Role::Service';
+
+__PACKAGE__->meta->make_immutable;
+no Moose;
+
+1;
diff --git a/lib/MooseX/Bread/Board/Literal.pm b/lib/MooseX/Bread/Board/Literal.pm
new file mode 100644
index 0000000..bf5944a
--- /dev/null
+++ b/lib/MooseX/Bread/Board/Literal.pm
@@ -0,0 +1,10 @@
+package MooseX::Bread::Board::Literal;
+use Moose;
+
+extends 'Bread::Board::Literal';
+with 'MooseX::Bread::Board::Role::Service';
+
+__PACKAGE__->meta->make_immutable;
+no Moose;
+
+1;
diff --git a/lib/MooseX/Bread/Board/Meta/Role/Attribute.pm b/lib/MooseX/Bread/Board/Meta/Role/Attribute.pm
new file mode 100644
index 0000000..a7ecb59
--- /dev/null
+++ b/lib/MooseX/Bread/Board/Meta/Role/Attribute.pm
@@ -0,0 +1,109 @@
+package MooseX::Bread::Board::Meta::Role::Attribute;
+use Moose::Role;
+
+use Bread::Board::Types;
+
+use MooseX::Bread::Board::BlockInjection;
+use MooseX::Bread::Board::ConstructorInjection;
+use MooseX::Bread::Board::Literal;
+
+has class => (
+ is => 'ro',
+ isa => 'Str',
+ predicate => 'has_class',
+);
+
+has block => (
+ is => 'ro',
+ isa => 'CodeRef',
+ predicate => 'has_block',
+);
+
+# has_value is already a method
+has literal_value => (
+ is => 'ro',
+ isa => 'Str|CodeRef',
+ init_arg => 'value',
+ predicate => 'has_literal_value',
+);
+
+has lifecycle => (
+ is => 'ro',
+ isa => 'Str',
+ predicate => 'has_lifecycle',
+);
+
+has dependencies => (
+ is => 'ro',
+ isa => 'Bread::Board::Service::Dependencies',
+ coerce => 1,
+ predicate => 'has_dependencies',
+);
+
+after attach_to_class => sub {
+ my $self = shift;
+
+ my $meta = $self->associated_class;
+ my $attr_reader = $self->get_read_method;
+
+ my %params = (
+ associated_attribute => $self,
+ name => $self->name,
+ ($self->has_lifecycle
+ ? (lifecycle => $self->lifecycle)
+ : ()),
+ ($self->has_dependencies
+ ? (dependencies => $self->dependencies)
+ : ()),
+ );
+
+ my $service;
+ if ($self->has_class) {
+ $service = MooseX::Bread::Board::ConstructorInjection->new(
+ %params,
+ class => $self->class,
+ )
+ }
+ elsif ($self->has_block) {
+ $service = MooseX::Bread::Board::BlockInjection->new(
+ %params,
+ block => $self->block,
+ )
+ }
+ elsif ($self->has_literal_value) {
+ $service = MooseX::Bread::Board::Literal->new(
+ %params,
+ value => $self->literal_value,
+ )
+ }
+ else {
+ return;
+ }
+
+ $meta->add_service($service);
+};
+
+around get_value => sub {
+ my $orig = shift;
+ my $self = shift;
+ my ($instance) = @_;
+
+ return $self->$orig($instance)
+ if $self->has_value($instance);
+
+ return $instance->get_service($self->name)->get;
+};
+
+around inline_get => sub {
+ my $orig = shift;
+ my $self = shift;
+ my ($instance) = @_;
+
+ return 'return (' . $self->inline_has($instance) . ')' . "\n"
+ . '? (' . $self->$orig($instance) . ')' . "\n"
+ . ': (' . $instance . '->get_service(\'' . $self->name . '\')->get);';
+};
+
+no Moose::Role;
+
+1;
diff --git a/lib/MooseX/Bread/Board/Meta/Role/Class.pm b/lib/MooseX/Bread/Board/Meta/Role/Class.pm
new file mode 100644
index 0000000..652d0b7
--- /dev/null
+++ b/lib/MooseX/Bread/Board/Meta/Role/Class.pm
@@ -0,0 +1,19 @@
+package MooseX::Bread::Board::Meta::Role::Class;
+use Moose::Role;
+
+use Bread::Board::Service;
+
+has services => (
+ traits => ['Array'],
+ isa => 'ArrayRef[Bread::Board::Service]',
+ default => sub { [] },
+ handles => {
+ add_service => 'push',
+ services => 'elements',
+ has_services => 'count',
+ },
+);
+
+no Moose::Role;
+
+1;
diff --git a/lib/MooseX/Bread/Board/Role/Object.pm b/lib/MooseX/Bread/Board/Role/Object.pm
new file mode 100644
index 0000000..552bc75
--- /dev/null
+++ b/lib/MooseX/Bread/Board/Role/Object.pm
@@ -0,0 +1,27 @@
+package MooseX::Bread::Board::Role::Object;
+use Moose::Role;
+use Bread::Board;
+
+has name => (
+ is => 'rw',
+ isa => 'Str',
+ lazy => 1,
+ default => sub { shift->meta->name },
+);
+
+sub BUILD { }
+after BUILD => sub {
+ my $self = shift;
+
+ my $meta = Class::MOP::class_of($self);
+ return unless $meta->has_services;
+
+ for my $service ($meta->services) {
+ $self->add_service($service->clone);
+ }
+};
+
+no Bread::Board;
+no Moose::Role;
+
+1;
diff --git a/lib/MooseX/Bread/Board/Role/Service.pm b/lib/MooseX/Bread/Board/Role/Service.pm
new file mode 100644
index 0000000..8442e3a
--- /dev/null
+++ b/lib/MooseX/Bread/Board/Role/Service.pm
@@ -0,0 +1,32 @@
+package MooseX::Bread::Board::Role::Service;
+use Moose::Role;
+
+has associated_attribute => (
+ is => 'ro',
+ isa => 'Class::MOP::Attribute',
+ required => 1,
+ weak_ref => 1,
+);
+
+around get => sub {
+ my $orig = shift;
+ my $self = shift;
+
+ my $container = $self;
+ until (!defined($container)
+ || ($container->isa('Bread::Board::Container')
+ && $container->does('MooseX::Bread::Board::Role::Object'))) {
+ $container = $container->parent;
+ }
+ die "Couldn't find associated object!" unless defined $container;
+
+ if ($self->associated_attribute->has_value($container)) {
+ return $self->associated_attribute->get_value($container);
+ }
+
+ return $self->$orig(@_);
+};
+
+no Moose::Role;
+
+1;