1#!./perl 2# 3# check UNIVERSAL 4# 5 6BEGIN { 7 chdir 't' if -d 't'; 8 @INC = '../lib'; 9 $| = 1; 10 require "./test.pl"; 11} 12 13plan tests => 144; 14 15$a = {}; 16bless $a, "Bob"; 17ok $a->isa("Bob"); 18 19package Human; 20sub eat {} 21 22package Female; 23@ISA=qw(Human); 24 25package Alice; 26@ISA=qw(Bob Female); 27sub sing; 28sub drink { return "drinking " . $_[1] } 29sub new { bless {} } 30 31$Alice::VERSION = 2.718; 32 33{ 34 package Cedric; 35 our @ISA; 36 use base qw(Human); 37} 38 39{ 40 package Programmer; 41 our $VERSION = 1.667; 42 43 sub write_perl { 1 } 44} 45 46package main; 47 48 49 50$a = new Alice; 51 52ok $a->isa("Alice"); 53ok $a->isa("main::Alice"); # check that alternate class names work 54 55ok(("main::Alice"->new)->isa("Alice")); 56 57ok $a->isa("Bob"); 58ok $a->isa("main::Bob"); 59 60ok $a->isa("Female"); 61 62ok ! $a->isa("Female\0NOT REALLY!"), "->isa is nul-clean."; 63 64ok $a->isa("Human"); 65 66ok ! $a->isa("Male"); 67 68ok ! $a->isa('Programmer'); 69 70ok $a->isa("HASH"); 71 72ok $a->can("eat"); 73ok ! $a->can("eat\0Except not!"), "->can is nul-clean."; 74ok ! $a->can("sleep"); 75ok my $ref = $a->can("drink"); # returns a coderef 76is $a->$ref("tea"), "drinking tea"; # ... which works 77ok $ref = $a->can("sing"); 78eval { $a->$ref() }; 79ok $@; # ... but not if no actual subroutine 80 81ok (!Cedric->isa('Programmer')); 82 83ok (Cedric->isa('Human')); 84 85push(@Cedric::ISA,'Programmer'); 86 87ok (Cedric->isa('Programmer')); 88 89{ 90 package Alice; 91 base::->import('Programmer'); 92} 93 94ok $a->isa('Programmer'); 95ok $a->isa("Female"); 96 97@Cedric::ISA = qw(Bob); 98 99ok (!Cedric->isa('Programmer')); 100 101my $b = 'abc'; 102my @refs = qw(SCALAR SCALAR LVALUE GLOB ARRAY HASH CODE); 103my @vals = ( \$b, \3.14, \substr($b,1,1), \*b, [], {}, sub {} ); 104for ($p=0; $p < @refs; $p++) { 105 for ($q=0; $q < @vals; $q++) { 106 is UNIVERSAL::isa($vals[$p], $refs[$q]), ($p==$q or $p+$q==1); 107 }; 108}; 109 110ok UNIVERSAL::can(23, "can"); 111++${"23::foo"}; 112ok UNIVERSAL::can("23", "can"), '"23" can can when the pack exists'; 113ok UNIVERSAL::can(23, "can"), '23 can can when the pack exists'; 114sub IO::Handle::turn {} 115ok UNIVERSAL::can(*STDOUT, 'turn'), 'globs with IOs can'; 116ok UNIVERSAL::can(\*STDOUT, 'turn'), 'globrefs with IOs can'; 117ok UNIVERSAL::can("STDOUT", 'turn'), 'IO barewords can'; 118 119ok $a->can("VERSION"); 120 121ok $a->can("can"); 122ok ! $a->can("export_tags"); # a method in Exporter 123 124cmp_ok eval { $a->VERSION }, '==', 2.718; 125 126ok ! (eval { $a->VERSION(2.719) }); 127like $@, qr/^Alice version 2.719 required--this is only version 2.718 at /; 128 129ok (eval { $a->VERSION(2.718) }); 130is $@, ''; 131 132ok ! (eval { $a->VERSION("version") }); 133like $@, qr/^Invalid version format/; 134 135$aversion::VERSION = "version"; 136ok ! (eval { aversion->VERSION(2.719) }); 137like $@, qr/^Invalid version format/; 138 139my $subs = join ' ', sort grep { defined &{"UNIVERSAL::$_"} } keys %UNIVERSAL::; 140## The test for import here is *not* because we want to ensure that UNIVERSAL 141## can always import; it is an historical accident that UNIVERSAL can import. 142if ('a' lt 'A') { 143 is $subs, "can import isa DOES VERSION"; 144} else { 145 is $subs, "DOES VERSION can import isa"; 146} 147 148ok $a->isa("UNIVERSAL"); 149 150ok ! UNIVERSAL::isa([], "UNIVERSAL"); 151 152ok ! UNIVERSAL::can({}, "can"); 153 154ok UNIVERSAL::isa(Alice => "UNIVERSAL"); 155 156cmp_ok UNIVERSAL::can(Alice => "can"), '==', \&UNIVERSAL::can; 157 158# now use UNIVERSAL.pm and see what changes 159eval "use UNIVERSAL"; 160 161ok $a->isa("UNIVERSAL"); 162 163my $sub2 = join ' ', sort grep { defined &{"UNIVERSAL::$_"} } keys %UNIVERSAL::; 164# XXX import being here is really a bug 165if ('a' lt 'A') { 166 is $sub2, "can import isa DOES VERSION"; 167} else { 168 is $sub2, "DOES VERSION can import isa"; 169} 170 171eval 'sub UNIVERSAL::sleep {}'; 172ok $a->can("sleep"); 173 174ok UNIVERSAL::can($b, "can"); 175 176ok ! $a->can("export_tags"); # a method in Exporter 177 178ok ! UNIVERSAL::isa("\xff\xff\xff\0", 'HASH'); 179 180{ 181 package Pickup; 182 no warnings "deprecated"; 183 use UNIVERSAL qw( isa can VERSION ); 184 185 ::ok isa "Pickup", UNIVERSAL; 186 ::cmp_ok can( "Pickup", "can" ), '==', \&UNIVERSAL::can; 187 ::ok VERSION "UNIVERSAL" ; 188} 189 190{ 191 # test isa() and can() on magic variables 192 "Human" =~ /(.*)/; 193 ok $1->isa("Human"); 194 ok $1->can("eat"); 195 package HumanTie; 196 sub TIESCALAR { bless {} } 197 sub FETCH { "Human" } 198 tie my($x), "HumanTie"; 199 ::ok $x->isa("Human"); 200 ::ok $x->can("eat"); 201} 202 203# bugid 3284 204# a second call to isa('UNIVERSAL') when @ISA is null failed due to caching 205 206@X::ISA=(); 207my $x = {}; bless $x, 'X'; 208ok $x->isa('UNIVERSAL'); 209ok $x->isa('UNIVERSAL'); 210 211 212# Check that the "historical accident" of UNIVERSAL having an import() 213# method doesn't effect anyone else. 214eval { Some::Package->import("bar") }; 215is $@, ''; 216 217 218# This segfaulted in a blead. 219fresh_perl_is('package Foo; Foo->VERSION; print "ok"', 'ok'); 220 221# So did this. 222fresh_perl_is('$:; UNIVERSAL::isa(":","Unicode::String");print "ok"','ok'); 223 224package Foo; 225 226sub DOES { 1 } 227 228package Bar; 229 230@Bar::ISA = 'Foo'; 231 232package Baz; 233 234package main; 235ok( Foo->DOES( 'bar' ), 'DOES() should call DOES() on class' ); 236ok( Bar->DOES( 'Bar' ), '... and should fall back to isa()' ); 237ok( Bar->DOES( 'Foo' ), '... even when inherited' ); 238ok( Baz->DOES( 'Baz' ), '... even without inheriting any other DOES()' ); 239ok( ! Baz->DOES( 'Foo' ), '... returning true or false appropriately' ); 240 241ok( ! "T"->DOES( "T\0" ), 'DOES() is nul-clean' ); 242ok( ! Baz->DOES( "Baz\0Boy howdy" ), 'DOES() is nul-clean' ); 243 244package Pig; 245package Bodine; 246Bodine->isa('Pig'); 247*isa = \&UNIVERSAL::isa; 248eval { isa({}, 'HASH') }; 249::is($@, '', "*isa correctly found"); 250 251package main; 252eval { UNIVERSAL::DOES([], "foo") }; 253like( $@, qr/Can't call method "DOES" on unblessed reference/, 254 'DOES call error message says DOES, not isa' ); 255 256# Tests for can seem to be split between here and method.t 257# Add the verbatim perl code mentioned in the comments of 258# http://www.xray.mpe.mpg.de/mailing-lists/perl5-porters/2001-05/msg01710.html 259# but never actually tested. 260is(UNIVERSAL->can("NoSuchPackage::foo"), undef); 261 262@splatt::ISA = 'zlopp'; 263ok (splatt->isa('zlopp')); 264ok (!splatt->isa('plop')); 265 266# This should reset the ->isa lookup cache 267@splatt::ISA = 'plop'; 268# And here is the new truth. 269ok (!splatt->isa('zlopp')); 270ok (splatt->isa('plop')); 271 272use warnings "deprecated"; 273{ 274 my $m; 275 local $SIG{__WARN__} = sub { $m = $_[0] }; 276 eval "use UNIVERSAL 'can'"; 277 like($m, qr/^UNIVERSAL->import is deprecated/, 278 "deprecation warning for UNIVERSAL->import('can')"); 279 280 undef $m; 281 eval "use UNIVERSAL"; 282 is($m, undef, 283 "no deprecation warning for UNIVERSAL->import"); 284} 285 286# Test: [perl #66112]: change @ISA inside sub isa 287{ 288 package RT66112::A; 289 290 package RT66112::B; 291 292 sub isa { 293 my $self = shift; 294 @ISA = qw/RT66112::A/; 295 return $self->SUPER::isa(@_); 296 } 297 298 package RT66112::C; 299 300 package RT66112::D; 301 302 sub isa { 303 my $self = shift; 304 @RT66112::E::ISA = qw/RT66112::A/; 305 return $self->SUPER::isa(@_); 306 } 307 308 package RT66112::E; 309 310 package main; 311 312 @RT66112::B::ISA = qw//; 313 @RT66112::C::ISA = qw/RT66112::B/; 314 @RT66112::T1::ISA = qw/RT66112::C/; 315 ok(RT66112::T1->isa('RT66112::C'), "modify \@ISA in isa (RT66112::T1 isa RT66112::C)"); 316 317 @RT66112::B::ISA = qw//; 318 @RT66112::C::ISA = qw/RT66112::B/; 319 @RT66112::T2::ISA = qw/RT66112::C/; 320 ok(RT66112::T2->isa('RT66112::B'), "modify \@ISA in isa (RT66112::T2 isa RT66112::B)"); 321 322 @RT66112::B::ISA = qw//; 323 @RT66112::C::ISA = qw/RT66112::B/; 324 @RT66112::T3::ISA = qw/RT66112::C/; 325 ok(RT66112::T3->isa('RT66112::A'), "modify \@ISA in isa (RT66112::T3 isa RT66112::A)") or require mro, diag "@{mro::get_linear_isa('RT66112::T3')}"; 326 327 @RT66112::E::ISA = qw/RT66112::D/; 328 @RT66112::T4::ISA = qw/RT66112::E/; 329 ok(RT66112::T4->isa('RT66112::E'), "modify \@ISA in isa (RT66112::T4 isa RT66112::E)"); 330 331 @RT66112::E::ISA = qw/RT66112::D/; 332 @RT66112::T5::ISA = qw/RT66112::E/; 333 ok(! RT66112::T5->isa('RT66112::D'), "modify \@ISA in isa (RT66112::T5 not isa RT66112::D)"); 334 335 @RT66112::E::ISA = qw/RT66112::D/; 336 @RT66112::T6::ISA = qw/RT66112::E/; 337 ok(RT66112::T6->isa('RT66112::A'), "modify \@ISA in isa (RT66112::T6 isa RT66112::A)"); 338} 339 340ok(Undeclared->can("can")); 341sub Undeclared::foo { } 342ok(Undeclared->can("foo")); 343ok(!Undeclared->can("something_else")); 344 345ok(Undeclared->isa("UNIVERSAL")); 346 347# keep this at the end to avoid messing up earlier tests, since it modifies 348# @UNIVERSAL::ISA 349@UNIVERSAL::ISA = ('UniversalParent'); 350{ package UniversalIsaTest1; } 351ok(UniversalIsaTest1->isa('UniversalParent')); 352ok(UniversalIsaTest2->isa('UniversalParent')); 353