+ - Bring back 5.8.1 compat
+
0.009007 - 2011-02-25
- I botched the copyright. re-disting.
use strict;
use warnings FATAL => 'all';
-use 5.008003;
+use 5.008001;
use ExtUtils::MakeMaker;
(do 'maint/Makefile.PL.include' or die $@) unless -f 'META.yml';
my ($self, $me, $name, $spec, $value) = @_;
my $name_str = perlstring $name;
my $simple = "${me}->{${name_str}} = ${value}";
+
if ($spec->{weak_ref}) {
require Scalar::Util;
- "Scalar::Util::weaken(${simple})";
+
+ # Perl < 5.8.3 can't weaken refs to readonly vars
+ # (e.g. string constants). This *can* be solved by:
+ #
+ #Internals::SetReadWrite($foo);
+ #Scalar::Util::weaken ($foo);
+ #Internals::SetReadOnly($foo);
+ #
+ # but requires XS and is just too damn crazy
+ # so simply throw a better exception
+ Moo::_Utils::lt_5_8_3() ? <<"EOC" : "Scalar::Util::weaken(${simple})";
+
+ eval { Scalar::Util::weaken($simple); 1 } or do {
+ if( \$@ =~ /Modification of a read-only value attempted/) {
+ require Carp;
+ Carp::croak( sprintf (
+ 'Reference to readonly value in "%s" can not be weakened on Perl < 5.8.3',
+ $name_str,
+ ) );
+ } else {
+ die \$@;
+ }
+ };
+EOC
} else {
$simple;
}
sub _getglob { \*{$_[0]} }
sub _getstash { \%{"$_[0]::"} }
+BEGIN {
+ *lt_5_8_3 = $] < 5.008003
+ ? sub () { 1 }
+ : sub () { 0 }
+ ;
+}
+
use strictures 1;
use base qw(Exporter);
has one => (is => 'ro', weak_ref => 1);
}
-my $ref = \'yay';
-
+my $ref = {};
my $foo = Foo->new(one => $ref);
-
-is(${$foo->one},'yay', 'value present');
+is($foo->one, $ref, 'value present');
ok(Scalar::Util::isweak($foo->{one}), 'value weakened');
+undef $ref;
+ok (!defined $foo->{one}, 'weak value gone');
+
+# test readonly SVs
+sub mk_ref { \ 'yay' };
+my $foo_ro = eval { Foo->new(one => mk_ref()) };
+if ($] < 5.008003) {
+ like(
+ $@,
+ qr/\QReference to readonly value in "one" can not be weakened on Perl < 5.8.3/,
+ 'Expected exception thrown on old perls'
+ );
+}
+else {
+ is(${$foo_ro->one},'yay', 'value present');
+ ok(Scalar::Util::isweak($foo_ro->{one}), 'value weakened');
+
+ { no warnings 'redefine'; *mk_ref = sub {} }
+ ok (!defined $foo_ro->{one}, 'optree reaped, ro static value gone');
+}
done_testing;
+# work around RT#67692
+use Moo::_Utils;
use strictures 1;
+
use Test::More;
-use Moo::_Utils;
local @INC = (sub {
return unless $_[1] eq 'Foo/Bar.pm';
my $u_one = unquote_sub $one;
is_deeply(
- [ keys %EVALED ], [ qw(one two) ],
+ [ sort keys %EVALED ], [ qw(one two) ],
'Both subs evaled'
);