This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
dounwind(): do a POPBLOCK for final cx frame.
[perl5.git] / t / op / bless.t
index 3aaceb8..69217fd 100644 (file)
@@ -1,51 +1,56 @@
 #!./perl
 
-print "1..31\n";
-
 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) = @_;
-    return "" if (
-       ref($object) eq $package
-       && "$object" =~ /^\Q$package\E=(\w+)\(0x([0-9a-f]+)\)$/
-       && $1 eq $type
-       # in 64-bit platforms hex warns for 32+ -bit values
-       && do { no warnings 'portable'; hex($2) == $object }
-    );
     print "# $object $package $type\n";
-    return "not ";
+    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";
-print expected($a1, "A", "HASH"), "ok 1\n";
+expected($a1, "A", "HASH");
 $b1 = bless [], "B";
-print expected($b1, "B", "ARRAY"), "ok 2\n";
+expected($b1, "B", "ARRAY");
 $c1 = bless \(map "$_", "test"), "C";
-print expected($c1, "C", "SCALAR"), "ok 3\n";
+expected($c1, "C", "SCALAR");
 our $test = "foo"; $d1 = bless \*test, "D";
-print expected($d1, "D", "GLOB"), "ok 4\n";
+expected($d1, "D", "GLOB");
 $e1 = bless sub { 1 }, "E";
-print expected($e1, "E", "CODE"), "ok 5\n";
+expected($e1, "E", "CODE");
 $f1 = bless \[], "F";
-print expected($f1, "F", "REF"), "ok 6\n";
+expected($f1, "F", "REF");
 $g1 = bless \substr("test", 1, 2), "G";
-print expected($g1, "G", "LVALUE"), "ok 7\n";
+expected($g1, "G", "LVALUE");
 
 # blessing ref to object doesn't modify object
 
-print expected(bless(\$a1, "F"), "F", "REF"), "ok 8\n";
-print expected($a1, "A", "HASH"), "ok 9\n";
+expected(bless(\$a1, "F"), "F", "REF");
+expected($a1, "A", "HASH");
 
 # reblessing does modify object
 
 bless $a1, "A2";
-print expected($a1, "A2", "HASH"), "ok 10\n";
+expected($a1, "A2", "HASH");
 
 # local and my
 {
@@ -53,37 +58,36 @@ print expected($a1, "A2", "HASH"), "ok 10\n";
     local $b1 = bless [], "B3";
     my $c1 = bless $c1, "C3";          # should rebless outer $c1
     our $test2 = ""; my $d1 = bless \*test2, "D3";
-    print expected($a1, "A3", "HASH"), "ok 11\n";
-    print expected($b1, "B3", "ARRAY"), "ok 12\n";
-    print expected($c1, "C3", "SCALAR"), "ok 13\n";
-    print expected($d1, "D3", "GLOB"), "ok 14\n";
+    expected($a1, "A3", "HASH");
+    expected($b1, "B3", "ARRAY");
+    expected($c1, "C3", "SCALAR");
+    expected($d1, "D3", "GLOB");
 }
-print expected($a1, "A3", "HASH"), "ok 15\n";
-print expected($b1, "B", "ARRAY"), "ok 16\n";
-print expected($c1, "C3", "SCALAR"), "ok 17\n";
-print expected($d1, "D", "GLOB"), "ok 18\n";
+expected($a1, "A3", "HASH");
+expected($b1, "B", "ARRAY");
+expected($c1, "C3", "SCALAR");
+expected($d1, "D", "GLOB");
 
 # class is magic
 "E" =~ /(.)/;
-print expected(bless({}, $1), "E", "HASH"), "ok 19\n";
+expected(bless({}, $1), "E", "HASH");
 {
     local $! = 1;
     my $string = "$!";
     $! = 2;    # attempt to avoid cached string
     $! = 1;
-    print expected(bless({}, $!), $string, "HASH"), "ok 20\n";
+    expected(bless({}, $!), $string, "HASH");
 
 # ref is ref to magic
     {
        {
            package F;
-           sub test { ${$_[0]} eq $string or print "not " }
+           sub test { main::is(${$_[0]}, $string) }
        }
        $! = 2;
        $f1 = bless \$!, "F";
        $! = 1;
        $f1->test;
-       print "ok 21\n";
     }
 }
 
@@ -91,30 +95,30 @@ print expected(bless({}, $1), "E", "HASH"), "ok 19\n";
 ### example of magic variable that is a reference??
 
 # no class, or empty string (with a warning), or undef (with two)
-print expected(bless([]), 'main', "ARRAY"), "ok 22\n";
+expected(bless([]), 'main', "ARRAY");
 {
     local $SIG{__WARN__} = sub { push @w, join '', @_ };
     use warnings;
 
     $m = bless [];
-    print expected($m, 'main', "ARRAY"), "ok 23\n";
-    print @w ? "not ok 24\t# @w\n" : "ok 24\n";
+    expected($m, 'main', "ARRAY");
+    is (scalar @w, 0);
 
     @w = ();
     $m = bless [], '';
-    print expected($m, 'main', "ARRAY"), "ok 25\n";
-    print @w != 1 ? "not ok 26\t# @w\n" : "ok 26\n";
+    expected($m, 'main', "ARRAY");
+    is (scalar @w, 1);
 
     @w = ();
     $m = bless [], undef;
-    print expected($m, 'main', "ARRAY"), "ok 27\n";
-    print @w != 2 ? "not ok 28\t# @w\n" : "ok 28\n";
+    expected($m, 'main', "ARRAY");
+    is (scalar @w, 2);
 }
 
 # class is a ref
 $a1 = bless {}, "A4";
 $b1 = eval { bless {}, $a1 };
-print $@ ? "ok 29\n" : "not ok 29\t# $b1\n";
+like ($@, qr/^Attempt to bless into a reference at /, "class is a ref");
 
 # class is an overloaded ref
 {
@@ -123,5 +127,54 @@ print $@ ? "ok 29\n" : "not ok 29\t# $b1\n";
 }
 $h1 = bless {}, "H4";
 $c4 = eval { bless \$test, $h1 };
-print expected($c4, 'C4', "SCALAR"), "ok 30\n";
-print $@ ? "not ok 31\t# $@" : "ok 31\n";
+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'
+}