summaryrefslogtreecommitdiff
path: root/t/op/bless.t
blob: 6aea7ba7e0b871899efde53cc75aae3d13655e40 (plain)
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
#!./perl

BEGIN {
    chdir 't' if -d 't';
    @INC = '../lib';
    require './test.pl';
}

plan (106);

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);
    "$object" =~ $r;
    is($1, $type);
    # in 64-bit platforms hex warns for 32+ -bit values
    cmp_ok(do {no warnings 'portable'; hex($2)}, '==', $object);
}

# 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 };
isnt ($@, '', "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");