Hi all, I need to stop looking at this.. I have a headache now..
I'm messing around with building a Plack app and had some really odd behaviour which I tracked back and boiled down to the test cases below. (unfortunately the result was my app connecting to a separate dev database after creating an empty test database and telling me a user existed where I knew it didn't.. took me a while to get past that..) anyhoo.. can someone please explain the oddities I'm seeing in these tests? My::Builder works as expected until I call make_immutable on it, then it returns undef. My::Builder2 is the same as My::Builder except - the 'app' attribute is lazy. - it's been made immutable it works as expected. My:Builder3 is the same as My::Builder except - it's been made immutable - I renamed the 'app' attribute as 'attr2'.. it works as expected. My::Builder4 is the same as My::Builder except - attr1 uses lazy_build - it's been made immutable it fails, but it returns attr1's default value please tell me I'm doing something stupid so I can stop trying to work it all out.. 8) cheers, J use strict; use warnings; use Test::More; { package My::Builder; use Moose; has attr1 => ( is => 'ro', default => 'default value' ); has app => ( is => 'ro', builder => '_build_app' ); sub _build_app{ shift->attr1; } sub web_app{ my $self = shift; return sub { $self->app }; } package My::Builder2; use Moose; has attr1 => ( is => 'ro', default => 'default value' ); has app => ( is => 'ro', builder => '_build_app', lazy => 1 ); sub _build_app{ shift->attr1; } sub web_app{ my $self = shift; return sub { $self->app }; } __PACKAGE__->meta->make_immutable; package My::Builder3; use Moose; has attr1 => ( is => 'ro', default => 'default value' ); has attr2 => ( is => 'ro', builder => '_build_attr2' ); sub _build_attr2{ shift->attr1; } sub web_app{ my $self = shift; return sub { $self->attr2 }; } __PACKAGE__->meta->make_immutable; package My::Builder4; use Moose; has attr1 => ( is => 'ro', lazy_build => 1 ); sub _build_attr1{ 'default value' } has app => ( is => 'ro', builder => '_build_app' ); sub _build_app{ shift->attr1; } sub web_app{ my $self = shift; return sub { $self->app }; } __PACKAGE__->meta->make_immutable; } my $app = My::Builder->new( attr1 => 'my value' )->web_app; is $app->(), 'my value', 'no make immutable or lazy ok'; $app = My::Builder2->new( attr1 => 'my value' )->web_app; is $app->(), 'my value', 'make_immutable with lazy ok'; $app = My::Builder3->new( attr1 => 'my value' )->web_app; is $app->(), 'my value', 'make_immutable without lazy breaks.. not!'; My::Builder->meta->make_immutable; $app = My::Builder->new( attr1 => 'my value' )->web_app; is $app->(), 'my value', 'make_immutable without lazy breaks (returns undef)'; $app = My::Builder4->new( attr1 => 'my value' )->web_app; is $app->(), 'my value', 'make_immutable without lazy breaks (returns default value)'; done_testing(); $ prove -lv t/999-make-immutable-breaksit.t t/999-make-immutable-breaksit.t .. ok 1 - no make immutable or lazy ok ok 2 - make_immutable with lazy ok ok 3 - make_immutable without lazy breaks.. not! not ok 4 - make_immutable without lazy breaks (returns undef) # Failed test 'make_immutable without lazy breaks (returns undef)' # at t/999-make-immutable-breaksit.t line 86. # got: undef # expected: 'my value' not ok 5 - make_immutable without lazy breaks (returns default value) # Failed test 'make_immutable without lazy breaks (returns default value)' # at t/999-make-immutable-breaksit.t line 89. # got: 'default value' # expected: 'my value' 1..5 # Looks like you failed 2 tests of 5. Dubious, test returned 2 (wstat 512, 0x200) Failed 2/5 subtests Test Summary Report ------------------- t/999-make-immutable-breaksit.t (Wstat: 512 Tests: 5 Failed: 2) Failed tests: 4-5 Non-zero exit status: 2 Files=1, Tests=5, 0 wallclock secs ( 0.02 usr 0.00 sys + 0.18 cusr 0.01 csys = 0.21 CPU) Result: FAIL -- Jason Galea Web Developer Ph 07 40556926 Mob 04 12345 534 www.eightdegrees.com.au