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' );