skeleton BUILDALL support
Matt S Trout [Wed, 20 Jan 2010 14:56:54 +0000 (14:56 +0000)]
lib/Web/Simple/Application.pm
t/buildall.t [new file with mode: 0644]

index 99a59a3..c115e6e 100644 (file)
@@ -61,7 +61,25 @@ use warnings FATAL => 'all';
 sub new {
   my ($class, $data) = @_;
   my $config = { $class->_default_config, %{($data||{})->{config}||{}} };
-  bless({ config => $config }, $class);
+  my $new = bless({ config => $config }, $class);
+  $new->BUILDALL($data);
+  $new;
+}
+
+sub BUILDALL {
+  my ($self, $data) = @_;
+  my $targ = ref($self);
+  my @targ;
+  while ($targ->isa(__PACKAGE__) and $targ ne __PACKAGE__) {
+    push(@targ, "${targ}::BUILD")
+      if do { no strict 'refs'; defined *{"${targ}::BUILD"}{CODE} };
+    my @targ_isa = do { no strict 'refs'; @{"${targ}::ISA"} };
+    die "${targ} uses Multiple Inheritance: ISA is: ".join ', ', @targ_isa
+      if @targ_isa > 1;
+    $targ = $targ_isa[0];
+  }
+  $self->$_($data) for reverse @targ;
+  return;
 }
 
 sub _setup_default_config {
diff --git a/t/buildall.t b/t/buildall.t
new file mode 100644 (file)
index 0000000..8d676ab
--- /dev/null
@@ -0,0 +1,23 @@
+use Test::More 'no_plan';
+
+use Web::Simple 'Fork';
+
+my @run;
+
+sub Fork::BUILD { push @run, [ FORK => $_[1] ] }
+
+@Knife::ISA = 'Fork';
+
+@Spoon::ISA = 'Knife';
+
+sub Spoon::BUILD { push @run, [ SPOON => $_[1] ] }
+
+bless({}, 'Fork')->BUILDALL('data');
+
+is_deeply(\@run, [ [ FORK => 'data' ] ], 'Single class ok');
+
+@run = ();
+
+bless({}, 'Spoon')->BUILDALL('data');
+
+is_deeply(\@run, [ [ FORK => 'data' ], [ SPOON => 'data' ] ], 'Subclass ok');