@@ -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();