1#!./perl 2# 3# check UNIVERSAL 4# 5 6BEGIN { 7 chdir 't' if -d 't'; 8 require './test.pl'; 9 set_up_inc(qw '../lib ../dist/base/lib'); 10 $| = 1; 11 require "./test.pl"; 12} 13 14plan tests => 144; 15 16$a = {}; 17bless $a, "Bob"; 18ok $a->isa("Bob"); 19 20package Human; 21sub eat {} 22 23package Female; 24@ISA=qw(Human); 25 26package Alice; 27@ISA=qw(Bob Female); 28sub sing; 29sub drink { return "drinking " . $_[1] } 30sub new { bless {} } 31 32$Alice::VERSION = 2.718; 33 34{ 35 package Cedric; 36 our @ISA; 37 use base qw(Human); 38} 39 40{ 41 package Programmer; 42 our $VERSION = 1.667; 43 44 sub write_perl { 1 } 45} 46 47package main; 48 49 50 51$a = new Alice; 52 53ok $a->isa("Alice"); 54ok $a->isa("main::Alice"); # check that alternate class names work 55 56ok(("main::Alice"->new)->isa("Alice")); 57 58ok $a->isa("Bob"); 59ok $a->isa("main::Bob"); 60 61ok $a->isa("Female"); 62 63ok ! $a->isa("Female\0NOT REALLY!"), "->isa is nul-clean."; 64 65ok $a->isa("Human"); 66 67ok ! $a->isa("Male"); 68 69ok ! $a->isa('Programmer'); 70 71ok $a->isa("HASH"); 72 73ok $a->can("eat"); 74ok ! $a->can("eat\0Except not!"), "->can is nul-clean."; 75ok ! $a->can("sleep"); 76ok my $ref = $a->can("drink"); # returns a coderef 77is $a->$ref("tea"), "drinking tea"; # ... which works 78ok $ref = $a->can("sing"); 79eval { $a->$ref() }; 80ok $@; # ... but not if no actual subroutine 81 82ok (!Cedric->isa('Programmer')); 83 84ok (Cedric->isa('Human')); 85 86push(@Cedric::ISA,'Programmer'); 87 88ok (Cedric->isa('Programmer')); 89 90{ 91 package Alice; 92 base::->import('Programmer'); 93} 94 95ok $a->isa('Programmer'); 96ok $a->isa("Female"); 97 98@Cedric::ISA = qw(Bob); 99 100ok (!Cedric->isa('Programmer')); 101 102my $b = 'abc'; 103my @refs = qw(SCALAR SCALAR LVALUE GLOB ARRAY HASH CODE); 104my @vals = ( \$b, \3.14, \substr($b,1,1), \*b, [], {}, sub {} ); 105for ($p=0; $p < @refs; $p++) { 106 for ($q=0; $q < @vals; $q++) { 107 is UNIVERSAL::isa($vals[$p], $refs[$q]), ($p==$q or $p+$q==1); 108 }; 109}; 110 111ok UNIVERSAL::can(23, "can"); 112++${"23::foo"}; 113ok UNIVERSAL::can("23", "can"), '"23" can can when the pack exists'; 114ok UNIVERSAL::can(23, "can"), '23 can can when the pack exists'; 115sub IO::Handle::turn {} 116ok UNIVERSAL::can(*STDOUT, 'turn'), 'globs with IOs can'; 117ok UNIVERSAL::can(\*STDOUT, 'turn'), 'globrefs with IOs can'; 118ok UNIVERSAL::can("STDOUT", 'turn'), 'IO barewords can'; 119 120ok $a->can("VERSION"); 121 122ok $a->can("can"); 123ok ! $a->can("export_tags"); # a method in Exporter 124 125cmp_ok eval { $a->VERSION }, '==', 2.718; 126 127ok ! (eval { $a->VERSION(2.719) }); 128like $@, qr/^Alice version 2.719 required--this is only version 2.718 at /; 129 130ok (eval { $a->VERSION(2.718) }); 131is $@, ''; 132 133ok ! (eval { $a->VERSION("version") }); 134like $@, qr/^Invalid version format/; 135 136$aversion::VERSION = "version"; 137ok ! (eval { aversion->VERSION(2.719) }); 138like $@, qr/^Invalid version format/; 139 140my $subs = join ' ', sort grep { defined &{"UNIVERSAL::$_"} } keys %UNIVERSAL::; 141if ('a' lt 'A') { 142 is $subs, "can import isa unimport DOES VERSION"; 143} else { 144 is $subs, "DOES VERSION can import isa unimport"; 145} 146 147ok $a->isa("UNIVERSAL"); 148 149ok ! UNIVERSAL::isa([], "UNIVERSAL"); 150 151ok ! UNIVERSAL::can({}, "can"); 152 153ok UNIVERSAL::isa(Alice => "UNIVERSAL"); 154 155cmp_ok UNIVERSAL::can(Alice => "can"), '==', \&UNIVERSAL::can; 156 157# now use UNIVERSAL.pm and see what changes 158eval "use UNIVERSAL"; 159 160ok $a->isa("UNIVERSAL"); 161 162my $sub2 = join ' ', sort grep { defined &{"UNIVERSAL::$_"} } keys %UNIVERSAL::; 163if ('a' lt 'A') { 164 is $sub2, "can import isa unimport DOES VERSION"; 165} else { 166 is $sub2, "DOES VERSION can import isa unimport"; 167} 168 169eval 'sub UNIVERSAL::sleep {}'; 170ok $a->can("sleep"); 171 172ok UNIVERSAL::can($b, "can"); 173 174ok ! $a->can("export_tags"); # a method in Exporter 175 176ok ! UNIVERSAL::isa("\xff\xff\xff\0", 'HASH'); 177 178{ 179 # test isa() and can() on magic variables 180 "Human" =~ /(.*)/; 181 ok $1->isa("Human"); 182 ok $1->can("eat"); 183 package HumanTie; 184 sub TIESCALAR { bless {} } 185 sub FETCH { "Human" } 186 tie my($x), "HumanTie"; 187 ::ok $x->isa("Human"); 188 ::ok $x->can("eat"); 189} 190 191# bugid 3284 192# a second call to isa('UNIVERSAL') when @ISA is null failed due to caching 193 194@X::ISA=(); 195my $x = {}; bless $x, 'X'; 196ok $x->isa('UNIVERSAL'); 197ok $x->isa('UNIVERSAL'); 198 199 200{ 201 my $err; 202 $SIG{__WARN__}= sub { die $_[0] }; 203 eval { Some::Package->import("bar") }; 204 my $err = $@; 205 $err=~s!t/op!op!; 206 is $err, "Attempt to call undefined import method with arguments (\"bar\")" 207 . " via package \"Some::Package\" (Perhaps you forgot to load" 208 . " the package?) at op/universal.t line 203.\n"; 209 eval { Some::Package->unimport(1.234) }; 210 $err = $@; 211 $err=~s!t/op!op!; 212 is $err, "Attempt to call undefined unimport method with arguments (\"1.234\")" 213 . " via package \"Some::Package\" (Perhaps you forgot to load" 214 . " the package?) at op/universal.t line 209.\n"; 215 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# Message-ID: E14ufZD-0007kD-00@libra.cus.cam.ac.uk 259# https://www.nntp.perl.org/group/perl.perl5.porters/2001/05/msg35327.html 260# but never actually tested. 261is(UNIVERSAL->can("NoSuchPackage::foo"), undef); 262 263@splatt::ISA = 'zlopp'; 264ok (splatt->isa('zlopp')); 265ok (!splatt->isa('plop')); 266 267# This should reset the ->isa lookup cache 268@splatt::ISA = 'plop'; 269# And here is the new truth. 270ok (!splatt->isa('zlopp')); 271ok (splatt->isa('plop')); 272 273use warnings "deprecated"; 274{ 275 my $m; 276 local $SIG{__WARN__} = sub { $m = $_[0] }; 277 eval "use UNIVERSAL 'can'"; 278 like($@, qr/^UNIVERSAL does not export anything\b/, 279 "error for UNIVERSAL->import('can')"); 280 is($m, undef, 281 "no deprecation warning for UNIVERSAL->import('can')"); 282 283 undef $m; 284 eval "use UNIVERSAL"; 285 is($@, "", 286 "no error for UNIVERSAL->import"); 287 is($m, undef, 288 "no deprecation warning for UNIVERSAL->import"); 289} 290 291# Test: [perl #66112]: change @ISA inside sub isa 292{ 293 package RT66112::A; 294 295 package RT66112::B; 296 297 sub isa { 298 my $self = shift; 299 @ISA = qw/RT66112::A/; 300 return $self->SUPER::isa(@_); 301 } 302 303 package RT66112::C; 304 305 package RT66112::D; 306 307 sub isa { 308 my $self = shift; 309 @RT66112::E::ISA = qw/RT66112::A/; 310 return $self->SUPER::isa(@_); 311 } 312 313 package RT66112::E; 314 315 package main; 316 317 @RT66112::B::ISA = qw//; 318 @RT66112::C::ISA = qw/RT66112::B/; 319 @RT66112::T1::ISA = qw/RT66112::C/; 320 ok(RT66112::T1->isa('RT66112::C'), "modify \@ISA in isa (RT66112::T1 isa RT66112::C)"); 321 322 @RT66112::B::ISA = qw//; 323 @RT66112::C::ISA = qw/RT66112::B/; 324 @RT66112::T2::ISA = qw/RT66112::C/; 325 ok(RT66112::T2->isa('RT66112::B'), "modify \@ISA in isa (RT66112::T2 isa RT66112::B)"); 326 327 @RT66112::B::ISA = qw//; 328 @RT66112::C::ISA = qw/RT66112::B/; 329 @RT66112::T3::ISA = qw/RT66112::C/; 330 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')}"; 331 332 @RT66112::E::ISA = qw/RT66112::D/; 333 @RT66112::T4::ISA = qw/RT66112::E/; 334 ok(RT66112::T4->isa('RT66112::E'), "modify \@ISA in isa (RT66112::T4 isa RT66112::E)"); 335 336 @RT66112::E::ISA = qw/RT66112::D/; 337 @RT66112::T5::ISA = qw/RT66112::E/; 338 ok(! RT66112::T5->isa('RT66112::D'), "modify \@ISA in isa (RT66112::T5 not isa RT66112::D)"); 339 340 @RT66112::E::ISA = qw/RT66112::D/; 341 @RT66112::T6::ISA = qw/RT66112::E/; 342 ok(RT66112::T6->isa('RT66112::A'), "modify \@ISA in isa (RT66112::T6 isa RT66112::A)"); 343} 344 345ok(Undeclared->can("can")); 346sub Undeclared::foo { } 347ok(Undeclared->can("foo")); 348ok(!Undeclared->can("something_else")); 349 350ok(Undeclared->isa("UNIVERSAL")); 351 352# keep this at the end to avoid messing up earlier tests, since it modifies 353# @UNIVERSAL::ISA 354@UNIVERSAL::ISA = ('UniversalParent'); 355{ package UniversalIsaTest1; } 356ok(UniversalIsaTest1->isa('UniversalParent')); 357ok(UniversalIsaTest2->isa('UniversalParent')); 358