use strict; use warnings; use Test::More 'tests' => 34; use Scalar::Util qw( reftype blessed ); #### my $package_0 = bless {}, '0'; ok( ! ref $package_0, '! ref $package_0' ); ok( ! blessed $package_0, '! blessed $package_0' ); is( reftype $package_0, ref {}, 'reftype $package_0' ); #### ok( ref $package_0 ne '', 'ref $package_0 ne ""' ); ok( defined blessed $package_0, 'defined blessed $package_0' ); #### package Super1; package Super2; package Sub; @Sub::ISA = qw( Super1 Super2 ); package main; my $sub_class = bless {}, 'Sub'; foreach my $class ( qw( Sub Super1 Super2 HASH ) ) { ok( $sub_class->isa( $class ), "\$sub_class->isa( '$class' )" ); } #### my $pretend_array = bless {}, 'ARRAY'; is( ref $pretend_array, ref [], 'ref of fake array looks real' ); ok( UNIVERSAL::isa( $pretend_array, 'ARRAY' ), 'UNIVERSAL::isa thinks it is an array' ); ok( $pretend_array->isa( 'ARRAY' ), '$pretend_array->isa( "ARRAY" )' ); #### package Void; sub void_sub { 'void sub' } package Empty; sub empty_sub { 'empty sub' } package Nothing; @Nothing::ISA = qw( Void Empty ); sub isa { 0 } my $uni_isa; BEGIN { $uni_isa = \&UNIVERSAL::isa; } { no warnings 'redefine'; # Subroutine UNIVERSAL::isa redefined sub UNIVERSAL::isa { ref $_[0] eq __PACKAGE__ ? 0 : goto &$uni_isa; } } package main; my @refs = ( ref {}, ref [], ref \do{my $x}, ref sub {}, ref qr// ); my $nothing = bless {}, 'Nothing'; foreach my $reftype ( @refs ) { ok( ! UNIVERSAL::isa( $nothing, $reftype ), "\$nothing is not $reftype" ); ok( ! $nothing->isa( $reftype ), "! \$nothing->isa( $reftype )" ); } ok( UNIVERSAL::isa( [], 'ARRAY' ), 'isa still works' ); ok( ! UNIVERSAL::isa( {}, 'ARRAY' ), 'isa still works (negation)' ); is( $nothing->void_sub(), 'void sub', 'method dispatch still works' ); #### my @nothing_isa; { no strict 'refs'; @nothing_isa = @{ ref( $nothing ) . '::ISA' }; } foreach my $class ( qw( Empty Void ) ) { ok( grep( $_ eq $class, @nothing_isa ), "\$nothing is a '$class' according to \@ISA" ); } #### package NotHash; use overload '%{}' => sub { {} }; sub new { bless [], shift } package main; my $not_hash = NotHash->new(); ok( ref $not_hash, '$not_hash is a reference' ); is( reftype $not_hash, reftype [], '$not_hash is an array reference' ); # Useless use of a variable in void context ok( eval { %{$not_hash}; 1 }, '$not_hash can be dereferenced as a hash' ); #### package EvilHash; use overload '%{}' => \&conditional_reference; sub conditional_reference { my @call = caller(1); if ( @call && $call[3] eq '(eval)' ) { die 'no testing'; } return { a => 1 }; } sub new { bless [], shift } package main; my $evil_hash = EvilHash->new(); ok( ref $evil_hash, '$evil_hash is a reference' ); is( reftype $evil_hash, reftype [], '$evil_hash is an array reference' ); # Useless use of a variable in void context ok( ! eval { %{$evil_hash}; 1 }, '$evil_hash will not be dereferenced inside eval' ); ok( scalar %{$evil_hash}, '$evil_hash allows dereference ouside eval' );