The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.
Changes 022
MANIFEST 01
META.json 1113
META.yml 1819
Makefile.PL 46
README 4248
cpanfile 35
lib/Class/Tiny.pm 6160
t/00-report-prereqs.t 46107
t/alfa.t 76
t/baker.t 101
t/charlie.t 16
t/delta.t 64
t/echo.t 81
t/foxtrot.t 11
t/golf.t 91
t/hotel.t 11
t/juliett.t 121
t/lib/Alfa.pm 11
t/lib/Baker.pm 11
t/lib/Charlie.pm 312
t/lib/Delta.pm 53
t/lib/Echo.pm 11
t/lib/Foxtrot.pm 11
t/lib/Golf.pm 11
t/lib/Hotel.pm 11
t/lib/India.pm 11
t/lib/Juliett.pm 11
t/lib/TestUtils.pm 11
xt/author/00-compile.t 24
xt/author/pod-spell.t 11
xt/release/distmeta.t 32
xt/release/pod-coverage.t 93
xt/release/pod-syntax.t 32
34 files changed (This is a version diff) 275339
@@ -1,5 +1,27 @@
 Revision history for Class-Tiny
 
+1.000     2014-07-16 09:55:29-04:00 America/New_York
+
+    [*** INCOMPATIBLE CHANGES ***]
+
+    - Attributes for custom accessors *MUST* be declared for them to be
+      set via the constructor.  It is no longer sufficient for a method of
+      the same name to exist.
+
+    - Unknown constructor arguments are ignored rather than fatal; they are
+      not included in the object.  Special instructions for using BUILD to
+      hide constructor arguments from validation are irrelevant and have
+      been removed.
+
+    - These changes make Class::Tiny-based classes easier to subclass by
+      more advanced object frameworks like Moose or Moo.
+
+0.015     2014-07-13 23:10:47-04:00 America/New_York
+
+    [CHANGED]
+
+    - lowered minimum perl to 5.006
+
 0.014     2013-11-28 07:12:14 America/New_York
 
     [FIXED]
@@ -1,3 +1,4 @@
+# This file was automatically generated by Dist::Zilla::Plugin::Manifest v5.019.
 CONTRIBUTING
 Changes
 LICENSE
@@ -4,7 +4,7 @@
       "David Golden <dagolden@cpan.org>"
    ],
    "dynamic_config" : 1,
-   "generated_by" : "Dist::Zilla version 5.006, CPAN::Meta::Converter version 2.132830",
+   "generated_by" : "Dist::Zilla version 5.019, CPAN::Meta::Converter version 2.141170",
    "license" : [
       "apache_2_0"
    ],
@@ -32,7 +32,7 @@
       },
       "develop" : {
          "requires" : {
-            "Dist::Zilla" : "5.006",
+            "Dist::Zilla" : "5",
             "Dist::Zilla::Plugin::OnlyCorePrereqs" : "0.003",
             "Dist::Zilla::Plugin::PerlVersionPrereqs" : "0",
             "Dist::Zilla::Plugin::Prereqs" : "0",
@@ -46,13 +46,14 @@
             "Test::CPAN::Meta" : "0",
             "Test::More" : "0",
             "Test::Pod" : "1.41",
-            "Test::Pod::Coverage" : "1.08"
+            "Test::Pod::Coverage" : "1.08",
+            "Test::Spelling" : "0.12"
          }
       },
       "runtime" : {
          "requires" : {
             "Carp" : "0",
-            "perl" : "5.008001",
+            "perl" : "5.006",
             "strict" : "0",
             "warnings" : "0"
          }
@@ -60,7 +61,7 @@
       "test" : {
          "recommends" : {
             "CPAN::Meta" : "0",
-            "CPAN::Meta::Requirements" : "0",
+            "CPAN::Meta::Requirements" : "2.120900",
             "Test::FailWarnings" : "0"
          },
          "requires" : {
@@ -71,18 +72,19 @@
             "Test::More" : "0.96",
             "base" : "0",
             "lib" : "0",
-            "subs" : "0"
+            "subs" : "0",
+            "version" : "0"
          }
       }
    },
    "provides" : {
       "Class::Tiny" : {
          "file" : "lib/Class/Tiny.pm",
-         "version" : "0.014"
+         "version" : "1.000"
       },
       "Class::Tiny::Object" : {
          "file" : "lib/Class/Tiny.pm",
-         "version" : "0.014"
+         "version" : "1.000"
       }
    },
    "release_status" : "stable",
@@ -97,14 +99,14 @@
          "web" : "https://github.com/dagolden/Class-Tiny"
       }
    },
-   "version" : "0.014",
+   "version" : "1.000",
    "x_authority" : "cpan:DAGOLDEN",
    "x_contributors" : [
-      "Dagfinn Ilmari Manns\u00e5ker <ilmari@ilmari.org>",
+      "Dagfinn Ilmari Mannsåker <ilmari@ilmari.org>",
       "Gelu Lupas <gelu@devnull.ro>",
       "Karen Etheridge <ether@cpan.org>",
       "Matt S Trout <mstrout@cpan.org>",
-      "Olivier Mengu\u00e9 <dolmen@cpan.org>",
+      "Olivier Mengué <dolmen@cpan.org>",
       "Toby Inkster <tobyink@cpan.org>"
    ]
 }
@@ -3,22 +3,23 @@ abstract: 'Minimalist class construction'
 author:
   - 'David Golden <dagolden@cpan.org>'
 build_requires:
-  Exporter: 0
-  ExtUtils::MakeMaker: 0
-  File::Spec::Functions: 0
-  List::Util: 0
-  Test::More: 0.96
-  base: 0
-  lib: 0
-  subs: 0
+  Exporter: '0'
+  ExtUtils::MakeMaker: '0'
+  File::Spec::Functions: '0'
+  List::Util: '0'
+  Test::More: '0.96'
+  base: '0'
+  lib: '0'
+  subs: '0'
+  version: '0'
 configure_requires:
-  ExtUtils::MakeMaker: 6.17
+  ExtUtils::MakeMaker: '6.17'
 dynamic_config: 1
-generated_by: 'Dist::Zilla version 5.006, CPAN::Meta::Converter version 2.132830'
+generated_by: 'Dist::Zilla version 5.019, CPAN::Meta::Converter version 2.141170'
 license: apache
 meta-spec:
   url: http://module-build.sourceforge.net/META-spec-v1.4.html
-  version: 1.4
+  version: '1.4'
 name: Class-Tiny
 no_index:
   directory:
@@ -31,20 +32,20 @@ no_index:
 provides:
   Class::Tiny:
     file: lib/Class/Tiny.pm
-    version: 0.014
+    version: '1.000'
   Class::Tiny::Object:
     file: lib/Class/Tiny.pm
-    version: 0.014
+    version: '1.000'
 requires:
-  Carp: 0
-  perl: 5.008001
-  strict: 0
-  warnings: 0
+  Carp: '0'
+  perl: '5.006'
+  strict: '0'
+  warnings: '0'
 resources:
   bugtracker: https://github.com/dagolden/Class-Tiny/issues
   homepage: https://github.com/dagolden/Class-Tiny
   repository: https://github.com/dagolden/Class-Tiny.git
-version: 0.014
+version: '1.000'
 x_authority: cpan:DAGOLDEN
 x_contributors:
   - 'Dagfinn Ilmari Mannsåker <ilmari@ilmari.org>'
@@ -1,8 +1,9 @@
 
+# This file was automatically generated by Dist::Zilla::Plugin::MakeMaker v5.019.
 use strict;
 use warnings;
 
-use 5.008001;
+use 5.006;
 
 use ExtUtils::MakeMaker 6.17;
 
@@ -11,7 +12,6 @@ use ExtUtils::MakeMaker 6.17;
 my %WriteMakefileArgs = (
   "ABSTRACT" => "Minimalist class construction",
   "AUTHOR" => "David Golden <dagolden\@cpan.org>",
-  "BUILD_REQUIRES" => {},
   "CONFIGURE_REQUIRES" => {
     "ExtUtils::MakeMaker" => "6.17"
   },
@@ -32,9 +32,10 @@ my %WriteMakefileArgs = (
     "Test::More" => "0.96",
     "base" => 0,
     "lib" => 0,
-    "subs" => 0
+    "subs" => 0,
+    "version" => 0
   },
-  "VERSION" => "0.014",
+  "VERSION" => "1.000",
   "test" => {
     "TESTS" => "t/*.t"
   }
@@ -52,6 +53,7 @@ my %FallbackPrereqs = (
   "lib" => 0,
   "strict" => 0,
   "subs" => 0,
+  "version" => 0,
   "warnings" => 0
 );
 
@@ -2,7 +2,7 @@ NAME
     Class::Tiny - Minimalist class construction
 
 VERSION
-    version 0.014
+    version 1.000
 
 SYNOPSIS
     In Person.pm:
@@ -30,9 +30,9 @@ SYNOPSIS
 
       my $obj = Employee->new( name => "Larry", ssn => "111-22-3333" );
 
-      # unknown attributes are fatal:
-      eval { Employee->new( name => "Larry", OS => "Linux" ) };
-      die "Error creating Employee: $@" if $@;
+      # unknown attributes are ignored
+      my $obj = Employee->new( name => "Larry", OS => "Linux" );
+      # $obj->{OS} does not exist
 
 DESCRIPTION
     This module offers a minimalist class construction kit in around 120
@@ -50,8 +50,6 @@ DESCRIPTION
 
     *   "new" takes a hash reference or list of key/value pairs
 
-    *   "new" has heuristics to catch constructor attribute typos
-
     *   "new" calls "BUILD" for each class from parent to child
 
     *   superclass provides a "DESTROY" method
@@ -116,9 +114,32 @@ USAGE
 
         sub id { ... }
 
-    By declaring "id" also with Class::Tiny, you include it in the list of
-    known attributes for introspection. Default values will not be set for
-    custom accessors unless you handle that yourself.
+    Even if you pre-declare a method name, you must include it in the
+    attribute list for Class::Tiny to register it as a valid attribute.
+
+    If you set a default for a custom accessor, your accessor will need to
+    retrieve the default and do something with it:
+
+        package Foo::Bar;
+
+        use subs 'id';
+
+        use Class::Tiny qw( name ), { id => sub { int(rand(2*31)) } };
+
+        sub id {
+            my $self = shift;
+            if (@_) {
+                return $self->{id} = shift;
+            }
+            elsif ( exists $self->{id} ) {
+                return $self->{id};
+            }
+            else {
+                my $defaults =
+                    Class::Tiny->get_all_attribute_defaults_for( ref $self );
+                return $self->{id} = $defaults->{id}->();
+            }
+        }
 
   Class::Tiny::Object is your base class
     If your class does not already inherit from some class, then
@@ -153,14 +174,12 @@ USAGE
         $obj = Foo::Bar->new( { name => "David" } );
 
     If a reference is passed as a single argument, it must be able to be
-    dereferenced as a hash or an exception is thrown. A shallow copy is made
-    of the reference provided.
+    dereferenced as a hash or an exception is thrown.
 
-    In order to help catch typos in constructor arguments, any argument that
-    it is not also a valid method (e.g. an accessor or other method) will
-    result in a fatal exception. This is not perfect, but should catch
-    typical transposition typos. Also see "BUILD" for how to explicitly hide
-    non-attribute, non-method arguments if desired.
+    Unknown attributes in the constructor arguments will be ignored. Prior
+    to version 1.000, unknown attributes were an error, but this made it
+    harder for people to cleanly subclass Class::Tiny classes so this
+    feature was removed.
 
   BUILD
     If your class or any superclass defines a "BUILD" method, it will be
@@ -168,36 +187,24 @@ USAGE
     child class after the object has been created.
 
     It is passed the constructor arguments as a hash reference. The return
-    value is ignored. Use "BUILD" for validation or setting default values.
+    value is ignored. Use "BUILD" for validation, checking required
+    attributes or setting default values that depend on other attributes.
 
         sub BUILD {
             my ($self, $args) = @_;
-            $self->foo(42) unless defined $self->foo;
-            croak "Foo must be non-negative" if $self->foo < 0;
-        }
 
-    If you want to hide a non-attribute constructor argument from
-    validation, delete it from the passed-in argument hash reference.
+            for my $req ( qw/name age/ ) {
+                croak "$req attribute required" unless defined $self->$req;
+            }
 
-        sub BUILD {
-            my ($self, $args) = @_;
+            croak "Age must be non-negative" if $self->age < 0;
 
-            if ( delete $args->{do_something_special} ) {
-                ...
-            }
+            $self->msg( "Hello " . $self->name );
         }
 
     The argument reference is a copy, so deleting elements won't affect data
-    in the object. You have to delete it from both if that's what you want.
-
-        sub BUILD {
-            my ($self, $args) = @_;
-
-            if ( delete $args->{do_something_special} ) {
-                delete $self->{do_something_special};
-                ...
-            }
-        }
+    in the original (but changes will be passed to other BUILD methods in
+    @ISA).
 
   DEMOLISH
     Class::Tiny provides a "DESTROY" method. If your class or any superclass
@@ -236,10 +243,10 @@ USAGE
     attempting to extend Class::Tiny itself should use these instead of
     mocking up a call to "import".
 
-    When the first object is created, linearized @ISA and various
-    subroutines references are cached for speed. Ensure that all inheritance
-    and methods are in place before creating objects. (You don't want to be
-    changing that once you create objects anyway, right?)
+    When the first object is created, linearized @ISA, the valid attribute
+    list and various subroutine references are cached for speed. Ensure that
+    all inheritance and methods are in place before creating objects. (You
+    don't want to be changing that once you create objects anyway, right?)
 
 RATIONALE
   Why this instead of Object::Tiny or Class::Accessor or something else?
@@ -273,7 +280,6 @@ RATIONALE
      provides new                       yes     yes       yes
      provides DESTROY                   yes     no        no
      new takes either hashref or list   yes     no (list) no (hash)
-     new validates arguments            yes     no        no
      Moo(se)-like BUILD/DEMOLISH        yes     no        no
      no extraneous methods via @ISA     yes     yes       no
 
@@ -1,5 +1,5 @@
 requires "Carp" => "0";
-requires "perl" => "5.008001";
+requires "perl" => "5.006";
 requires "strict" => "0";
 requires "warnings" => "0";
 
@@ -12,11 +12,12 @@ on 'test' => sub {
   requires "base" => "0";
   requires "lib" => "0";
   requires "subs" => "0";
+  requires "version" => "0";
 };
 
 on 'test' => sub {
   recommends "CPAN::Meta" => "0";
-  recommends "CPAN::Meta::Requirements" => "0";
+  recommends "CPAN::Meta::Requirements" => "2.120900";
   recommends "Test::FailWarnings" => "0";
 };
 
@@ -25,7 +26,7 @@ on 'configure' => sub {
 };
 
 on 'develop' => sub {
-  requires "Dist::Zilla" => "5.006";
+  requires "Dist::Zilla" => "5";
   requires "Dist::Zilla::Plugin::OnlyCorePrereqs" => "0.003";
   requires "Dist::Zilla::Plugin::PerlVersionPrereqs" => "0";
   requires "Dist::Zilla::Plugin::Prereqs" => "0";
@@ -40,4 +41,5 @@ on 'develop' => sub {
   requires "Test::More" => "0";
   requires "Test::Pod" => "1.41";
   requires "Test::Pod::Coverage" => "1.08";
+  requires "Test::Spelling" => "0.12";
 };
@@ -1,11 +1,11 @@
-use 5.008001;
+use 5.006;
 use strict;
 no strict 'refs';
 use warnings;
 
 package Class::Tiny;
 # ABSTRACT: Minimalist class construction
-our $VERSION = '0.014'; # VERSION
+our $VERSION = '1.000'; # VERSION
 
 use Carp ();
 
@@ -78,9 +78,9 @@ sub get_all_attribute_defaults_for {
 
 package Class::Tiny::Object;
 # ABSTRACT: Base class for classes built with Class::Tiny
-our $VERSION = '0.014'; # VERSION
+our $VERSION = '1.000'; # VERSION
 
-my ( %LINEAR_ISA_CACHE, %BUILD_CACHE, %DEMOLISH_CACHE, %CAN_CACHE );
+my ( %LINEAR_ISA_CACHE, %BUILD_CACHE, %DEMOLISH_CACHE, %ATTR_CACHE );
 
 my $_PRECACHE = sub {
     my ($class) = @_;
@@ -93,12 +93,15 @@ my $_PRECACHE = sub {
         $BUILD_CACHE{$s}    = *{"$s\::BUILD"}{CODE};
         $DEMOLISH_CACHE{$s} = *{"$s\::DEMOLISH"}{CODE};
     }
+    $ATTR_CACHE{$class} =
+      { map { $_ => 1 } Class::Tiny->get_all_attributes_for($class) };
     return $LINEAR_ISA_CACHE{$class};
 };
 
 sub new {
-    my $class = shift;
-    my $linear_isa = $LINEAR_ISA_CACHE{$class} || $_PRECACHE->($class);
+    my $class       = shift;
+    my $linear_isa  = $LINEAR_ISA_CACHE{$class} || $_PRECACHE->($class);
+    my $valid_attrs = $ATTR_CACHE{$class};
 
     # handle hash ref or key/value arguments
     my $args;
@@ -114,21 +117,15 @@ sub new {
         Carp::croak("$class->new() got an odd number of elements");
     }
 
-    # create object and invoke BUILD
-    my $self = bless {%$args}, $class;
-    for my $s ( reverse @$linear_isa ) {
+    # create object and invoke BUILD (unless we were given __no_BUILD__)
+    my $self =
+      bless { map { $_ => $args->{$_} } grep { exists $valid_attrs->{$_} } keys %$args },
+      $class;
+    for my $s ( delete $args->{__no_BUILD__} ? () : reverse @$linear_isa ) {
         next unless my $builder = $BUILD_CACHE{$s};
         $builder->( $self, $args );
     }
 
-    # unknown attributes still in $args are fatal
-    my @bad;
-    for my $k ( keys %$args ) {
-        push( @bad, $k )
-          unless $CAN_CACHE{$class}{$k} ||= $self->can($k); # a heuristic to catch typos
-    }
-    Carp::croak("Invalid attributes for $class: @bad") if @bad;
-
     return $self;
 }
 
@@ -171,7 +168,7 @@ Class::Tiny - Minimalist class construction
 
 =head1 VERSION
 
-version 0.014
+version 1.000
 
 =head1 SYNOPSIS
 
@@ -200,9 +197,9 @@ In F<example.pl>:
 
   my $obj = Employee->new( name => "Larry", ssn => "111-22-3333" );
 
-  # unknown attributes are fatal:
-  eval { Employee->new( name => "Larry", OS => "Linux" ) };
-  die "Error creating Employee: $@" if $@;
+  # unknown attributes are ignored
+  my $obj = Employee->new( name => "Larry", OS => "Linux" );
+  # $obj->{OS} does not exist
 
 =head1 DESCRIPTION
 
@@ -237,10 +234,6 @@ C<new> takes a hash reference or list of key/value pairs
 
 =item *
 
-C<new> has heuristics to catch constructor attribute typos
-
-=item *
-
 C<new> calls C<BUILD> for each class from parent to child
 
 =item *
@@ -312,9 +305,32 @@ loading Class::Tiny:
 
     sub id { ... }
 
-By declaring C<id> also with Class::Tiny, you include it in the list of known
-attributes for introspection.  Default values will not be set for custom
-accessors unless you handle that yourself.
+Even if you pre-declare a method name, you must include it in the attribute
+list for Class::Tiny to register it as a valid attribute.
+
+If you set a default for a custom accessor, your accessor will need to retrieve
+the default and do something with it:
+
+    package Foo::Bar;
+
+    use subs 'id';
+
+    use Class::Tiny qw( name ), { id => sub { int(rand(2*31)) } };
+
+    sub id {
+        my $self = shift;
+        if (@_) {
+            return $self->{id} = shift;
+        }
+        elsif ( exists $self->{id} ) {
+            return $self->{id};
+        }
+        else {
+            my $defaults =
+                Class::Tiny->get_all_attribute_defaults_for( ref $self );
+            return $self->{id} = $defaults->{id}->();
+        }
+    }
 
 =head2 Class::Tiny::Object is your base class
 
@@ -350,14 +366,11 @@ of key/value pairs:
     $obj = Foo::Bar->new( { name => "David" } );
 
 If a reference is passed as a single argument, it must be able to be
-dereferenced as a hash or an exception is thrown.  A shallow copy is made of
-the reference provided.
+dereferenced as a hash or an exception is thrown.
 
-In order to help catch typos in constructor arguments, any argument that it is
-not also a valid method (e.g. an accessor or other method) will result in a
-fatal exception.  This is not perfect, but should catch typical transposition
-typos. Also see L</BUILD> for how to explicitly hide non-attribute, non-method
-arguments if desired.
+Unknown attributes in the constructor arguments will be ignored.  Prior to
+version 1.000, unknown attributes were an error, but this made it harder for
+people to cleanly subclass Class::Tiny classes so this feature was removed.
 
 =head2 BUILD
 
@@ -366,36 +379,23 @@ by the constructor from the furthest parent class down to the child class after
 the object has been created.
 
 It is passed the constructor arguments as a hash reference.  The return value
-is ignored.  Use C<BUILD> for validation or setting default values.
+is ignored.  Use C<BUILD> for validation, checking required attributes or
+setting default values that depend on other attributes.
 
     sub BUILD {
         my ($self, $args) = @_;
-        $self->foo(42) unless defined $self->foo;
-        croak "Foo must be non-negative" if $self->foo < 0;
-    }
 
-If you want to hide a non-attribute constructor argument from validation,
-delete it from the passed-in argument hash reference.
+        for my $req ( qw/name age/ ) {
+            croak "$req attribute required" unless defined $self->$req;
+        }
 
-    sub BUILD {
-        my ($self, $args) = @_;
+        croak "Age must be non-negative" if $self->age < 0;
 
-        if ( delete $args->{do_something_special} ) {
-            ...
-        }
+        $self->msg( "Hello " . $self->name );
     }
 
 The argument reference is a copy, so deleting elements won't affect data in the
-object. You have to delete it from both if that's what you want.
-
-    sub BUILD {
-        my ($self, $args) = @_;
-
-        if ( delete $args->{do_something_special} ) {
-            delete $self->{do_something_special};
-            ...
-        }
-    }
+original (but changes will be passed to other BUILD methods in C<@ISA>).
 
 =head2 DEMOLISH
 
@@ -435,10 +435,10 @@ C<create_attributes> to set up the C<@ISA> array and attributes.  Anyone
 attempting to extend Class::Tiny itself should use these instead of mocking up
 a call to C<import>.
 
-When the first object is created, linearized C<@ISA> and various subroutines
-references are cached for speed.  Ensure that all inheritance and methods are
-in place before creating objects. (You don't want to be changing that once you
-create objects anyway, right?)
+When the first object is created, linearized C<@ISA>, the valid attribute list
+and various subroutine references are cached for speed.  Ensure that all
+inheritance and methods are in place before creating objects. (You don't want
+to be changing that once you create objects anyway, right?)
 
 =for Pod::Coverage new get_all_attributes_for get_all_attribute_defaults_for
 prepare_class create_attributes
@@ -477,7 +477,6 @@ Specifically, here is how Class::Tiny ("C::T") compares to Object::Tiny
  provides new                       yes     yes       yes
  provides DESTROY                   yes     no        no
  new takes either hashref or list   yes     no (list) no (hash)
- new validates arguments            yes     no        no
  Moo(se)-like BUILD/DEMOLISH        yes     no        no
  no extraneous methods via @ISA     yes     yes       no
 
@@ -3,69 +3,130 @@
 use strict;
 use warnings;
 
-# This test was generated by Dist::Zilla::Plugin::Test::ReportPrereqs 0.010
+# This test was generated by Dist::Zilla::Plugin::Test::ReportPrereqs 0.013
 
 use Test::More tests => 1;
 
 use ExtUtils::MakeMaker;
 use File::Spec::Functions;
 use List::Util qw/max/;
+use version;
+
+# hide optional CPAN::Meta modules from prereq scanner
+# and check if they are available
+my $cpan_meta = "CPAN::Meta";
+my $cpan_meta_req = "CPAN::Meta::Requirements";
+my $HAS_CPAN_META = eval "require $cpan_meta"; ## no critic
+my $HAS_CPAN_META_REQ = eval "require $cpan_meta_req; $cpan_meta_req->VERSION('2.120900')";
+
+# Verify requirements?
+my $DO_VERIFY_PREREQS = 1;
+
+sub _merge_requires {
+    my ($collector, $prereqs) = @_;
+    for my $phase ( qw/configure build test runtime develop/ ) {
+        next unless exists $prereqs->{$phase};
+        if ( my $req = $prereqs->{$phase}{'requires'} ) {
+            my $cmr = CPAN::Meta::Requirements->from_string_hash( $req );
+            $collector->add_requirements( $cmr );
+        }
+    }
+}
+
+my %include = map {; $_ => 1 } qw(
 
-my @modules = qw(
-  CPAN::Meta
-  CPAN::Meta::Requirements
-  Carp
-  Exporter
-  ExtUtils::MakeMaker
-  File::Spec::Functions
-  List::Util
-  Test::FailWarnings
-  Test::More
-  base
-  lib
-  perl
-  strict
-  subs
-  warnings
 );
 
 my %exclude = map {; $_ => 1 } qw(
 
 );
 
-my ($source) = grep { -f $_ } qw/MYMETA.json MYMETA.yml META.json/;
-$source = "META.yml" unless defined $source;
-
-# replace modules with dynamic results from MYMETA.json if we can
-# (hide CPAN::Meta from prereq scanner)
-my $cpan_meta = "CPAN::Meta";
-my $cpan_meta_req = "CPAN::Meta::Requirements";
+# Add static prereqs to the included modules list
+my $static_prereqs = do { my $x = {
+       'configure' => {
+                        'requires' => {
+                                        'ExtUtils::MakeMaker' => '6.17'
+                                      }
+                      },
+       'develop' => {
+                      'requires' => {
+                                      'Dist::Zilla' => '5',
+                                      'Dist::Zilla::Plugin::OnlyCorePrereqs' => '0.003',
+                                      'Dist::Zilla::Plugin::PerlVersionPrereqs' => '0',
+                                      'Dist::Zilla::Plugin::Prereqs' => '0',
+                                      'Dist::Zilla::Plugin::RemovePrereqs' => '0',
+                                      'Dist::Zilla::PluginBundle::DAGOLDEN' => '0.052',
+                                      'File::Spec' => '0',
+                                      'File::Temp' => '0',
+                                      'IO::Handle' => '0',
+                                      'IPC::Open3' => '0',
+                                      'Pod::Coverage::TrustPod' => '0',
+                                      'Test::CPAN::Meta' => '0',
+                                      'Test::More' => '0',
+                                      'Test::Pod' => '1.41',
+                                      'Test::Pod::Coverage' => '1.08',
+                                      'Test::Spelling' => '0.12'
+                                    }
+                    },
+       'runtime' => {
+                      'requires' => {
+                                      'Carp' => '0',
+                                      'perl' => '5.006',
+                                      'strict' => '0',
+                                      'warnings' => '0'
+                                    }
+                    },
+       'test' => {
+                   'recommends' => {
+                                     'CPAN::Meta' => '0',
+                                     'CPAN::Meta::Requirements' => '2.120900',
+                                     'Test::FailWarnings' => '0'
+                                   },
+                   'requires' => {
+                                   'Exporter' => '0',
+                                   'ExtUtils::MakeMaker' => '0',
+                                   'File::Spec::Functions' => '0',
+                                   'List::Util' => '0',
+                                   'Test::More' => '0.96',
+                                   'base' => '0',
+                                   'lib' => '0',
+                                   'subs' => '0',
+                                   'version' => '0'
+                                 }
+                 }
+     };
+  $x;
+ };
+
+delete $static_prereqs->{develop} if not $ENV{AUTHOR_TESTING};
+$include{$_} = 1 for map { keys %$_ } map { values %$_ } values %$static_prereqs;
+
+# Merge requirements for major phases (if we can)
 my $all_requires;
-if ( -f $source && eval "require $cpan_meta" ) { ## no critic
+if ( $DO_VERIFY_PREREQS && $HAS_CPAN_META_REQ ) {
+    $all_requires = $cpan_meta_req->new;
+    _merge_requires($all_requires, $static_prereqs);
+}
+
+
+# Add dynamic prereqs to the included modules list (if we can)
+my ($source) = grep { -f } 'MYMETA.json', 'MYMETA.yml';
+if ( $source && $HAS_CPAN_META ) {
   if ( my $meta = eval { CPAN::Meta->load_file($source) } ) {
+    my $dynamic_prereqs = $meta->prereqs;
+    delete $dynamic_prereqs->{develop} if not $ENV{AUTHOR_TESTING};
+    $include{$_} = 1 for map { keys %$_ } map { values %$_ } values %$dynamic_prereqs;
 
-    # Get ALL modules mentioned in META (any phase/type)
-    my $prereqs = $meta->prereqs;
-    delete $prereqs->{develop} if not $ENV{AUTHOR_TESTING};
-    my %uniq = map {$_ => 1} map { keys %$_ } map { values %$_ } values %$prereqs;
-    $uniq{$_} = 1 for @modules; # don't lose any static ones
-    @modules = sort grep { ! $exclude{$_} } keys %uniq;
-
-    # If verifying, merge 'requires' only for major phases
-    if ( 1 ) {
-      $prereqs = $meta->effective_prereqs; # get the object, not the hash
-      if (eval "require $cpan_meta_req; 1") { ## no critic
-        $all_requires = $cpan_meta_req->new;
-        for my $phase ( qw/configure build test runtime/ ) {
-          $all_requires->add_requirements(
-            $prereqs->requirements_for($phase, 'requires')
-          );
-        }
-      }
+    if ( $DO_VERIFY_PREREQS && $HAS_CPAN_META_REQ ) {
+        _merge_requires($all_requires, $dynamic_prereqs);
     }
   }
 }
+else {
+  $source = 'static metadata';
+}
 
+my @modules = sort grep { ! $exclude{$_} } keys %include;
 my @reports = [qw/Version Module/];
 my @dep_errors;
 my $req_hash = defined($all_requires) ? $all_requires->as_string_hash : {};
@@ -81,7 +142,7 @@ for my $mod ( @modules ) {
     $ver = "undef" unless defined $ver; # Newer MM should do this anyway
     push @reports, [$ver, $mod];
 
-    if ( 1 && $all_requires ) {
+    if ( $DO_VERIFY_PREREQS && $all_requires ) {
       my $req = $req_hash->{$mod};
       if ( defined $req && length $req ) {
         if ( ! defined eval { version->parse($ver) } ) {
@@ -97,7 +158,7 @@ for my $mod ( @modules ) {
   else {
     push @reports, ["missing", $mod];
 
-    if ( 1 && $all_requires ) {
+    if ( $DO_VERIFY_PREREQS && $all_requires ) {
       my $req = $req_hash->{$mod};
       if ( defined $req && length $req ) {
         push @dep_errors, "$mod is not installed (version '$req' required)";
@@ -125,4 +186,4 @@ if ( @dep_errors ) {
 
 pass;
 
-# vim: ts=2 sts=2 sw=2 et:
+# vim: ts=4 sts=4 sw=4 et:
@@ -1,4 +1,4 @@
-use 5.008001;
+use 5.006;
 use strict;
 use warnings;
 use lib 't/lib';
@@ -58,13 +58,12 @@ subtest "attributes are RW" => sub {
     is( $obj->foo,     24, "accessing foo returns changed value" );
 };
 
-subtest "exceptions" => sub {
-    like(
-        exception { Alfa->new( foo => 23, bar => 42, baz => 13 ) },
-        qr/Invalid attributes for Alfa: baz/,
-        "creating object with 'baz' dies",
-    );
+subtest "unknown attributes stripped" => sub {
+    my $obj = new_ok( "Alfa", [ { wibble => 1 } ], "new( wibble => 1 )" );
+    ok( !exists $obj->{wibble}, "unknown attribute 'wibble' not in object" );
+};
 
+subtest "exceptions" => sub {
     like(
         exception { Alfa->new(qw/ foo bar baz/) },
         qr/Alfa->new\(\) got an odd number of elements/,
@@ -1,4 +1,4 @@
-use 5.008001;
+use 5.006;
 use strict;
 use warnings;
 use lib 't/lib';
@@ -59,15 +59,6 @@ subtest "attributes are RW" => sub {
     is( $obj->baz,     42, "accessing baz returns changed value" );
 };
 
-subtest "exceptions" => sub {
-    like(
-        exception { Baker->new( foo => 23, bar => 42, baz => 13, wibble => 0 ) },
-        qr/Invalid attributes for Baker: wibble/,
-        "creating object with 'wibble' dies",
-    );
-
-};
-
 done_testing;
 #
 # This file is part of Class-Tiny
@@ -1,4 +1,4 @@
-use 5.008001;
+use 5.006;
 use strict;
 use warnings;
 use lib 't/lib';
@@ -19,6 +19,11 @@ subtest "custom accessor" => sub {
     is_deeply( $obj->bar(qw/1 1 2 3 5/), [qw/1 1 2 3 5/], "bar is set" );
 };
 
+subtest "custom accessor with default" => sub {
+    my $obj = new_ok( "Charlie", [ foo => 13, bar => [42] ] );
+    is( $obj->baz, 23, "custom accessor has default" );
+};
+
 done_testing;
 #
 # This file is part of Class-Tiny
@@ -1,4 +1,4 @@
-use 5.008001;
+use 5.006;
 use strict;
 use warnings;
 use lib 't/lib';
@@ -14,11 +14,9 @@ subtest "attribute set as list" => sub {
     is( $obj->bar, 23, "bar is set" );
 };
 
-subtest "hiding constructor argument" => sub {
-    my $obj = new_ok( "Delta", [ foo => 42, bar => 23, hide_me => 1 ] );
-    is( $obj->foo, 42, "foo is set" );
-    is( $obj->bar, 23, "bar is set" );
-    is( $obj->{hide_me}, 1, "hidden constructor argument still in object" );
+subtest "__no_BUILD__" => sub {
+    my $obj = new_ok( "Delta", [ __no_BUILD__ => 1 ], "new( __no_BUILD__ => 1 )" );
+    is( $Delta::counter, 0, "BUILD method didn't run" );
 };
 
 subtest "destructor" => sub {
@@ -1,4 +1,4 @@
-use 5.008001;
+use 5.006;
 use strict;
 use warnings;
 use lib 't/lib';
@@ -24,13 +24,6 @@ subtest "destructor" => sub {
     is( $Delta::exception, 0, "cleanup worked in correct order" );
 };
 
-subtest "constructor argument heuristic hiding" => sub {
-    my $obj = new_ok( "Echo", [ foo => 42, bar => 23, a_method => 1 ] );
-    is( $obj->foo, 42, "foo is set" );
-    is( $obj->bar, 23, "bar is set" );
-    is( $obj->{a_method}, 1, "hidden constructor argument still in object" );
-};
-
 subtest "exceptions" => sub {
     like(
         exception { Echo->new( foo => 0, bar => 23 ) },
@@ -1,4 +1,4 @@
-use 5.008001;
+use 5.006;
 use strict;
 use warnings;
 use lib 't/lib';
@@ -1,4 +1,4 @@
-use 5.008001;
+use 5.006;
 use strict;
 use warnings;
 use lib 't/lib';
@@ -22,14 +22,6 @@ subtest "lazy defaults" => sub {
     isnt( $obj->wobble, $obj2->wobble, "coderefs run for each object" );
 };
 
-subtest "exceptions" => sub {
-    like(
-        exception { Golf->new( foo => 23, bar => 42, zoom => 13 ) },
-        qr/Invalid attributes for Golf: zoom/,
-        "creating object with 'baz' dies",
-    );
-};
-
 done_testing;
 #
 # This file is part of Class-Tiny
@@ -1,4 +1,4 @@
-use 5.008001;
+use 5.006;
 use strict;
 use warnings;
 use lib 't/lib';
@@ -1,4 +1,4 @@
-use 5.008001;
+use 5.006;
 use strict;
 use warnings;
 use lib 't/lib';
@@ -74,17 +74,6 @@ subtest "attributes are RW" => sub {
     is( $obj->kit,     31, "accessing kit rerutns changed value" );
 };
 
-subtest "exceptions" => sub {
-    like(
-        exception {
-            Juliett->new( foo => 23, bar => 42, baz => 13, qux => 11, kit => 31, wibble => 0 );
-        },
-        qr/Invalid attributes for Juliett: wibble/,
-        "creating object with 'wibble' dies",
-    );
-
-};
-
 done_testing;
 #
 # This file is part of Class-Tiny
@@ -1,4 +1,4 @@
-use 5.008001;
+use 5.006;
 use strict;
 use warnings;
 
@@ -1,4 +1,4 @@
-use 5.008001;
+use 5.006;
 use strict;
 use warnings;
 
@@ -1,12 +1,12 @@
-use 5.008001;
+use 5.006;
 use strict;
 use warnings;
 
 package Charlie;
 
-use subs qw/bar/;
+use subs qw/bar baz/;
 
-use Class::Tiny qw/foo bar/;
+use Class::Tiny qw/foo bar/, { baz => 23 };
 
 sub bar {
     my $self = shift;
@@ -16,4 +16,13 @@ sub bar {
     return $self->{bar};
 }
 
+sub baz {
+    my $self = shift;
+    if (@_) {
+        $self->{baz} = shift;
+    }
+    return $self->{baz} ||=
+      Class::Tiny->get_all_attribute_defaults_for( ref $self )->{baz};
+}
+
 1;
@@ -1,10 +1,10 @@
-use 5.008001;
+use 5.006;
 use strict;
 use warnings;
 
 package Delta;
 
-our $counter = 0;
+our $counter   = 0;
 our $exception = 0;
 
 use Carp ();
@@ -19,13 +19,11 @@ sub BUILD {
 
     $self->bar(42) unless defined $self->bar;
     $counter++;
-
-    delete $args->{hide_me};
 }
 
 sub DEMOLISH {
     my $self = shift;
-    $counter--;
+    $counter--   if $counter > 0;
     $exception++ if keys %$self > 2; # Echo will delete first
 }
 
@@ -1,4 +1,4 @@
-use 5.008001;
+use 5.006;
 use strict;
 use warnings;
 
@@ -1,4 +1,4 @@
-use 5.008001;
+use 5.006;
 use strict;
 use warnings;
 
@@ -1,4 +1,4 @@
-use 5.008001;
+use 5.006;
 use strict;
 use warnings;
 
@@ -1,4 +1,4 @@
-use 5.008001;
+use 5.006;
 use strict;
 use warnings;
 
@@ -1,4 +1,4 @@
-use 5.008001;
+use 5.006;
 use strict;
 use warnings;
 
@@ -1,4 +1,4 @@
-use 5.008001;
+use 5.006;
 use strict;
 use warnings;
 
@@ -1,4 +1,4 @@
-use 5.008001;
+use 5.006;
 use strict;
 use warnings;
 package TestUtils;
@@ -1,7 +1,8 @@
+use 5.006;
 use strict;
 use warnings;
 
-# this test was generated with Dist::Zilla::Plugin::Test::Compile 2.037
+# this test was generated with Dist::Zilla::Plugin::Test::Compile 2.043
 
 use Test::More  tests => 1 + ($ENV{AUTHOR_TESTING} ? 1 : 0);
 
@@ -24,11 +25,12 @@ use File::Spec;
 use IPC::Open3;
 use IO::Handle;
 
+open my $stdin, '<', File::Spec->devnull or die "can't open devnull: $!";
+
 my @warnings;
 for my $lib (@module_files)
 {
     # see L<perlfaq8/How can I capture STDERR from an external command?>
-    open my $stdin, '<', File::Spec->devnull or die "can't open devnull: $!";
     my $stderr = IO::Handle->new;
 
     my $pid = open3($stdin, '>&STDERR', $stderr, $^X, $inc_switch, '-e', "require q[$lib]");
@@ -2,7 +2,7 @@ use strict;
 use warnings;
 use Test::More;
 
-# generated by Dist::Zilla::Plugin::Test::PodSpelling 2.006001
+# generated by Dist::Zilla::Plugin::Test::PodSpelling 2.006008
 use Test::Spelling 0.12;
 use Pod::Wordlist;
 
@@ -1,7 +1,6 @@
 #!perl
+# This file was automatically generated by Dist::Zilla::Plugin::MetaTests.
 
-use Test::More;
+use Test::CPAN::Meta;
 
-eval "use Test::CPAN::Meta";
-plan skip_all => "Test::CPAN::Meta required for testing META.yml" if $@;
 meta_yaml_ok();
@@ -1,13 +1,7 @@
 #!perl
+# This file was automatically generated by Dist::Zilla::Plugin::PodCoverageTests.
 
-use Test::More;
-
-eval "use Test::Pod::Coverage 1.08";
-plan skip_all => "Test::Pod::Coverage 1.08 required for testing POD coverage"
-  if $@;
-
-eval "use Pod::Coverage::TrustPod";
-plan skip_all => "Pod::Coverage::TrustPod required for testing POD coverage"
-  if $@;
+use Test::Pod::Coverage 1.08;
+use Pod::Coverage::TrustPod;
 
 all_pod_coverage_ok({ coverage_class => 'Pod::Coverage::TrustPod' });
@@ -1,7 +1,6 @@
 #!perl
+# This file was automatically generated by Dist::Zilla::Plugin::PodSyntaxTests.
 use Test::More;
-
-eval "use Test::Pod 1.41";
-plan skip_all => "Test::Pod 1.41 required for testing POD" if $@;
+use Test::Pod 1.41;
 
 all_pod_files_ok();