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