1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180
|
#!./perl
BEGIN {
chdir 't' if -d 't';
@INC = '../lib';
require './test.pl';
}
plan (114);
# Please do not eliminate the plan. We have tests in DESTROY blocks.
sub expected {
my($object, $package, $type) = @_;
print "# $object $package $type\n";
is(ref($object), $package);
my $r = qr/^\Q$package\E=(\w+)\(0x([0-9a-f]+)\)$/;
like("$object", $r);
if ("$object" =~ $r) {
is($1, $type);
# in 64-bit platforms hex warns for 32+ -bit values
cmp_ok(do {no warnings 'portable'; hex($2)}, '==', $object);
}
else {
fail(); fail();
}
}
# test blessing simple types
$a1 = bless {}, "A";
expected($a1, "A", "HASH");
$b1 = bless [], "B";
expected($b1, "B", "ARRAY");
$c1 = bless \(map "$_", "test"), "C";
expected($c1, "C", "SCALAR");
our $test = "foo"; $d1 = bless \*test, "D";
expected($d1, "D", "GLOB");
$e1 = bless sub { 1 }, "E";
expected($e1, "E", "CODE");
$f1 = bless \[], "F";
expected($f1, "F", "REF");
$g1 = bless \substr("test", 1, 2), "G";
expected($g1, "G", "LVALUE");
# blessing ref to object doesn't modify object
expected(bless(\$a1, "F"), "F", "REF");
expected($a1, "A", "HASH");
# reblessing does modify object
bless $a1, "A2";
expected($a1, "A2", "HASH");
# local and my
{
local $a1 = bless $a1, "A3"; # should rebless outer $a1
local $b1 = bless [], "B3";
my $c1 = bless $c1, "C3"; # should rebless outer $c1
our $test2 = ""; my $d1 = bless \*test2, "D3";
expected($a1, "A3", "HASH");
expected($b1, "B3", "ARRAY");
expected($c1, "C3", "SCALAR");
expected($d1, "D3", "GLOB");
}
expected($a1, "A3", "HASH");
expected($b1, "B", "ARRAY");
expected($c1, "C3", "SCALAR");
expected($d1, "D", "GLOB");
# class is magic
"E" =~ /(.)/;
expected(bless({}, $1), "E", "HASH");
{
local $! = 1;
my $string = "$!";
$! = 2; # attempt to avoid cached string
$! = 1;
expected(bless({}, $!), $string, "HASH");
# ref is ref to magic
{
{
package F;
sub test { main::is(${$_[0]}, $string) }
}
$! = 2;
$f1 = bless \$!, "F";
$! = 1;
$f1->test;
}
}
# ref is magic
### example of magic variable that is a reference??
# no class, or empty string (with a warning), or undef (with two)
expected(bless([]), 'main', "ARRAY");
{
local $SIG{__WARN__} = sub { push @w, join '', @_ };
use warnings;
$m = bless [];
expected($m, 'main', "ARRAY");
is (scalar @w, 0);
@w = ();
$m = bless [], '';
expected($m, 'main', "ARRAY");
is (scalar @w, 1);
@w = ();
$m = bless [], undef;
expected($m, 'main', "ARRAY");
is (scalar @w, 2);
}
# class is a ref
$a1 = bless {}, "A4";
$b1 = eval { bless {}, $a1 };
like ($@, qr/^Attempt to bless into a reference at /, "class is a ref");
# class is an overloaded ref
{
package H4;
use overload '""' => sub { "C4" };
}
$h1 = bless {}, "H4";
$c4 = eval { bless \$test, $h1 };
is ($@, '', "class is an overloaded ref");
expected($c4, 'C4', "SCALAR");
{
my %h = 1..2;
my($k) = keys %h;
my $x=\$k;
bless $x, 'pam';
is(ref $x, 'pam');
my $a = bless \(keys %h), 'zap';
is(ref $a, 'zap');
}
bless [], "main::";
ok(1, 'blessing into main:: does not crash'); # [perl #87388]
sub _117941 { package _117941; bless [] }
delete $::{"_117941::"};
eval { _117941() };
like $@, qr/^Attempt to bless into a freed package at /,
'bless with one arg when current stash is freed';
for(__PACKAGE__) {
eval { bless \$_ };
like $@, qr/^Modification of a read-only value attempted/,
'read-only COWs cannot be blessed';
}
sub TIESCALAR { bless \(my $thing = pop), shift }
sub FETCH { ${$_[0]} }
tie $tied, main => $untied = [];
eval { bless $tied };
is ref $untied, "main", 'blessing through tied refs' or diag $@;
bless \$victim, "Food";
eval 'bless \$Food::bard, "Bard"';
sub Bard::DESTROY {
isnt ref(\$victim), '__ANON__',
'reblessing does not leave an object in limbo temporarily';
bless \$victim
}
undef *Food::;
{
my $w;
# This should catch ‘Attempt to free unreferenced scalar’.
local $SIG{__WARN__} = sub { $w .= shift };
bless \$victim;
is $w, undef,
'no warnings when reblessing inside DESTROY triggered by reblessing'
}
|