Skip Menu |

Preferred bug tracker

Please visit the preferred bug tracker to report your issue.

This queue is for tickets about the Mouse CPAN distribution.

Report information
The Basics
Id: 53286
Status: rejected
Priority: 0/
Queue: Mouse

People
Owner: Nobody in particular
Requestors: spang [...] mit.edu
Cc:
AdminCc:

Bug Information
Severity: Normal
Broken in:
  • 0.45
  • 0.4501
Fixed in: (no value)



Subject: attribute bug in XS version
The attached test file shows some code where the XS version of Mouse and the pure perl version give different behaviours. The pure perl behaviour is what I expect is the right behaviour, and is the behaviour that Mouse 0.40 and below have. The test fails for me using the XS version but not the pure perl version.

This is Perl 5.10.1 on Debian. I believe this affects all XS versions of Mouse, which I guess is everything after 0.40, but I've only tested with 0.45 and 0.4501.

Subject: bug.t
package Foo; use Mouse; has app_handle => ( is => 'rw', isa => 'Baz', required => 1, ); has handle => ( is => 'rw', isa => 'Int', # app_handle should not be undef here! default => sub { shift->app_handle->handle() }, ); no Mouse; 1; package Bar; use Mouse; has app_handle => ( is => 'rw', isa => 'Baz', required => 1, ); sub do_something { my $self = shift; my $foo = Foo->new( app_handle => $self->app_handle ); return $foo->handle; } no Mouse; 1; package Baz; use Mouse; sub handle { # print "This works correctly.\n"; return 1; } no Mouse; 1; package main; use strict; use warnings; use Test::More tests => 2; use Test::Exception; my $bar = Bar->new( app_handle => Baz->new() ); ok($bar, "Test class Bar instantiated w/attribute app_handle Baz"); # Trigger the default sub of baz's handle attribute, which tries to call # a method on an attribute which was set to an object passed in via the # constructor. lives_and { is($bar->do_something(), 1, "attribute was passed in okay") };
This is not a bug.

The code relies on the initialisation order of attributes, which is not guaranteed by either Moose or Mouse. Specifically,  it relies on the app_handle attribute being initialized before initializing handle.

Making the handle attribute lazy fixes the failure as app_handle is always initialized when calling the handle accessor after creating the instance. If you really want the instance to be set during construction-time instead of on the first call to the accessor the user makes, you can use the following idiom:

  sub BUILD {
    my ($self) = @_;
    $self->some_lazy_attribute;
  }