You can see in the MooseX Declare documentation that it implicitly uses namespace::autoclean. This automatic cleaning of imported subs ends up removing the special subs installed by overload as well. There is a bug filed on namespace::autoclean to fix this issue. Another workaround aside from what ikegami posted would be to use the 'is dirty' modifier to avoid the automatic cleaning.
Test:
use MooseX::Declare;
class InDeclare {
use overload '""' => \&to_string2;
has val => is => 'rw';
sub to_string2 { sprintf "(%s)", $_[0]->val }
};
class InDeclareDirty is dirty {
use overload '""' => \&to_string2;
has val => is => 'rw';
sub to_string2 { sprintf "(%s)", $_[0]->val }
};
package main;
use strict;
use warnings;
use Test::More;
my $d = InDeclare->new(val=>666);
is $d, "(666)", "mxd is ok"; # PASS: "(666)"
is "$d", "(666)", "mxd is ok (Q)"; # FAIL: "InDeclare=HASH(0x2166ab0)"
my $dd = InDeclareDirty->new(val=>6666);
is $dd, "(6666)", "mxdd is ok";
is "$dd", "(6666)", "mxdd is ok (Q)";
done_testing;
Results:
ok 1 - mxd is ok
not ok 2 - mxd is ok (Q)
# Failed test 'mxd is ok (Q)'
# at test.pl line 24.
# got: 'InDeclare=HASH(0x100e42bd0)'
# expected: '(666)'
ok 3 - mxdd is ok
ok 4 - mxdd is ok (Q)
1..4
# Looks like you failed 1 test of 4.