initial import master
Matt S Trout [Sat, 25 Aug 2012 20:13:23 +0000 (20:13 +0000)]
lib/Object/Inline.pm [new file with mode: 0644]
t/simple.t [new file with mode: 0644]

diff --git a/lib/Object/Inline.pm b/lib/Object/Inline.pm
new file mode 100644 (file)
index 0000000..def326d
--- /dev/null
@@ -0,0 +1,22 @@
+package Object::Inline;
+
+use strictures 1;
+use Package::Variant ();
+use Import::Into;
+
+sub import {
+  my $class = shift;
+  my $target = caller;
+  Package::Variant->import::into(
+    $target,
+    no_import => 1, make_variant => sub { $_[2]->($_[1]) },
+    @_,
+  );
+  no strict 'refs';
+  *{"${target}::object"} = sub (&;@) {
+    my $code = shift;
+    Package::Variant->build_variant_of($target, $code)->new(@_);
+  };
+}
+
+1;
diff --git a/t/simple.t b/t/simple.t
new file mode 100644 (file)
index 0000000..952ad50
--- /dev/null
@@ -0,0 +1,95 @@
+use strictures 1;
+use Test::More;
+
+{
+  package My::Logger;
+
+  use Moo;
+
+  has log_file_name => (is => 'ro');
+
+  package My::DB;
+
+  use Moo;
+
+  has $_ => (is => 'ro') for qw(dsn username password);
+
+  sub connect {
+    my $class = shift;
+    my %args; @args{qw(dsn username password)} = @_;
+    $class->new(\%args);
+  }
+
+  package My::App;
+
+  use Moo;
+
+  has $_ => (is => 'ro') for qw(logger db);
+}
+
+my $c = do {
+  package My::Builder;
+
+  use Object::Inline
+    importing => { 'Moo' => [] },
+    subs => [ qw(has before after around) ];
+
+  sub _subify {
+    ref($_[0]) eq 'CODE'
+      ? $_[0]
+      : do { my $v = $_[0]; sub { $v } }
+  }
+
+  sub static {
+    has $_[0] => (is => 'lazy');
+    install "_build_$_[0]" => _subify($_[1]);
+  }
+
+  sub dynamic {
+    install $_[0] => _subify($_[1]);
+  }
+
+  object {
+
+    static log_file_name => 'logfile.log';
+
+    static logger => sub {
+      My::Logger->new(log_file_name => $_[0]->log_file_name);
+    };
+
+    static database => sub {
+
+      object {
+        static dsn => "dbi:SQLite:dbname=my-app.db";
+
+        static username => 'user234';
+
+        static password => '****';
+
+        dynamic db => sub {
+          my $self = shift;
+          My::DB->connect($self->dsn, $self->username, $self->password);
+        };
+      };
+    };
+
+    dynamic application => sub {
+      my $self = shift;
+      My::App->new(logger => $self->logger, db => $self->database->db);
+    }
+  };
+};
+
+my $app = $c->application;
+
+ok($app->logger->isa('My::Logger'), 'Logger object exists');
+
+is($app->logger->log_file_name, 'logfile.log', 'log file name');
+
+ok($app->db->isa('My::DB'), 'DB object exists');
+
+is($app->db->dsn, "dbi:SQLite:dbname=my-app.db", 'DB object populated');
+
+done_testing;
+
+1;