1*5486feefSafresh1#!./perl 2256a93a4Safresh1 3256a93a4Safresh1BEGIN { 4256a93a4Safresh1 chdir 't' if -d 't'; 5256a93a4Safresh1 require './test.pl'; 6256a93a4Safresh1 set_up_inc('../lib'); 7256a93a4Safresh1} 8256a93a4Safresh1 9f2a19305Safresh1use v5.36; 10256a93a4Safresh1no warnings 'experimental::builtin'; 11256a93a4Safresh1 12256a93a4Safresh1package FetchStoreCounter { 13f2a19305Safresh1 sub TIESCALAR($class, @args) { bless \@args, $class } 14f2a19305Safresh1 15f2a19305Safresh1 sub FETCH($self) { $self->[0]->$*++ } 16f2a19305Safresh1 sub STORE($self, $) { $self->[1]->$*++ } 17256a93a4Safresh1} 18256a93a4Safresh1 19256a93a4Safresh1# booleans 20256a93a4Safresh1{ 21256a93a4Safresh1 use builtin qw( true false is_bool ); 22256a93a4Safresh1 23256a93a4Safresh1 ok(true, 'true is true'); 24256a93a4Safresh1 ok(!false, 'false is false'); 25256a93a4Safresh1 26256a93a4Safresh1 ok(is_bool(true), 'true is bool'); 27256a93a4Safresh1 ok(is_bool(false), 'false is bool'); 28256a93a4Safresh1 ok(!is_bool(undef), 'undef is not bool'); 29256a93a4Safresh1 ok(!is_bool(1), '1 is not bool'); 30256a93a4Safresh1 ok(!is_bool(""), 'empty is not bool'); 31256a93a4Safresh1 32256a93a4Safresh1 my $truevar = (5 == 5); 33256a93a4Safresh1 my $falsevar = (5 == 6); 34256a93a4Safresh1 35256a93a4Safresh1 ok(is_bool($truevar), '$truevar is bool'); 36256a93a4Safresh1 ok(is_bool($falsevar), '$falsevar is bool'); 37256a93a4Safresh1 38256a93a4Safresh1 ok(is_bool(is_bool(true)), 'is_bool true is bool'); 39256a93a4Safresh1 ok(is_bool(is_bool(123)), 'is_bool false is bool'); 40256a93a4Safresh1 41256a93a4Safresh1 # Invokes magic 42256a93a4Safresh1 43256a93a4Safresh1 tie my $tied, FetchStoreCounter => (\my $fetchcount, \my $storecount); 44256a93a4Safresh1 45256a93a4Safresh1 my $_dummy = is_bool($tied); 46256a93a4Safresh1 is($fetchcount, 1, 'is_bool() invokes FETCH magic'); 47256a93a4Safresh1 48256a93a4Safresh1 $tied = is_bool(false); 49f2a19305Safresh1 is($storecount, 1, 'is_bool() invokes STORE magic'); 50f2a19305Safresh1 51f2a19305Safresh1 is(prototype(\&builtin::is_bool), '$', 'is_bool prototype'); 52256a93a4Safresh1} 53256a93a4Safresh1 54*5486feefSafresh1# float constants 55*5486feefSafresh1{ 56*5486feefSafresh1 use builtin qw( inf nan ); 57*5486feefSafresh1 58*5486feefSafresh1 ok(inf, 'inf is true'); 59*5486feefSafresh1 ok(inf > 1E10, 'inf is bigger than 1E10'); 60*5486feefSafresh1 ok(inf == inf, 'inf is equal to inf'); 61*5486feefSafresh1 ok(inf == inf + 1, 'inf is equal to inf + 1'); 62*5486feefSafresh1 63*5486feefSafresh1 # Invoke the real XSUB 64*5486feefSafresh1 my $inf = ( \&builtin::inf )->(); 65*5486feefSafresh1 ok($inf == $inf + 1, 'inf returned by real xsub'); 66*5486feefSafresh1 67*5486feefSafresh1 ok(nan != nan, 'NaN is not equal to NaN'); 68*5486feefSafresh1 69*5486feefSafresh1 my $nan = ( \&builtin::nan )->(); 70*5486feefSafresh1 ok($nan != $nan, 'NaN returned by real xsub'); 71*5486feefSafresh1} 72*5486feefSafresh1 73256a93a4Safresh1# weakrefs 74256a93a4Safresh1{ 75256a93a4Safresh1 use builtin qw( is_weak weaken unweaken ); 76256a93a4Safresh1 77256a93a4Safresh1 my $arr = []; 78256a93a4Safresh1 my $ref = $arr; 79256a93a4Safresh1 80256a93a4Safresh1 ok(!is_weak($ref), 'ref is not weak initially'); 81256a93a4Safresh1 82256a93a4Safresh1 weaken($ref); 83256a93a4Safresh1 ok(is_weak($ref), 'ref is weak after weaken()'); 84256a93a4Safresh1 85256a93a4Safresh1 unweaken($ref); 86256a93a4Safresh1 ok(!is_weak($ref), 'ref is not weak after unweaken()'); 87256a93a4Safresh1 88256a93a4Safresh1 weaken($ref); 89256a93a4Safresh1 undef $arr; 90256a93a4Safresh1 is($ref, undef, 'ref is now undef after arr is cleared'); 91f2a19305Safresh1 92f2a19305Safresh1 is(prototype(\&builtin::weaken), '$', 'weaken prototype'); 93f2a19305Safresh1 is(prototype(\&builtin::unweaken), '$', 'unweaken prototype'); 94f2a19305Safresh1 is(prototype(\&builtin::is_weak), '$', 'is_weak prototype'); 95256a93a4Safresh1} 96256a93a4Safresh1 97256a93a4Safresh1# reference queries 98256a93a4Safresh1{ 99256a93a4Safresh1 use builtin qw( refaddr reftype blessed ); 100256a93a4Safresh1 101256a93a4Safresh1 my $arr = []; 102256a93a4Safresh1 my $obj = bless [], "Object"; 103256a93a4Safresh1 104256a93a4Safresh1 is(refaddr($arr), $arr+0, 'refaddr yields same as ref in numeric context'); 105256a93a4Safresh1 is(refaddr("not a ref"), undef, 'refaddr yields undef for non-reference'); 106256a93a4Safresh1 107256a93a4Safresh1 is(reftype($arr), "ARRAY", 'reftype yields type string'); 108256a93a4Safresh1 is(reftype($obj), "ARRAY", 'reftype yields basic container type for blessed object'); 109256a93a4Safresh1 is(reftype("not a ref"), undef, 'reftype yields undef for non-reference'); 110256a93a4Safresh1 111256a93a4Safresh1 is(blessed($arr), undef, 'blessed yields undef for non-object'); 112256a93a4Safresh1 is(blessed($obj), "Object", 'blessed yields package name for object'); 113256a93a4Safresh1 114256a93a4Safresh1 # blessed() as a boolean 115256a93a4Safresh1 is(blessed($obj) ? "YES" : "NO", "YES", 'blessed in boolean context still works'); 116256a93a4Safresh1 117256a93a4Safresh1 # blessed() appears false as a boolean on package "0" 118256a93a4Safresh1 is(blessed(bless [], "0") ? "YES" : "NO", "NO", 'blessed in boolean context handles "0" cornercase'); 119f2a19305Safresh1 120f2a19305Safresh1 is(prototype(\&builtin::blessed), '$', 'blessed prototype'); 121f2a19305Safresh1 is(prototype(\&builtin::refaddr), '$', 'refaddr prototype'); 122f2a19305Safresh1 is(prototype(\&builtin::reftype), '$', 'reftype prototype'); 123256a93a4Safresh1} 124256a93a4Safresh1 125256a93a4Safresh1# created_as_... 126256a93a4Safresh1{ 127256a93a4Safresh1 use builtin qw( created_as_string created_as_number ); 128256a93a4Safresh1 129256a93a4Safresh1 # some literal constants 130256a93a4Safresh1 ok(!created_as_string(undef), 'undef created as !string'); 131256a93a4Safresh1 ok(!created_as_number(undef), 'undef created as !number'); 132256a93a4Safresh1 133256a93a4Safresh1 ok( created_as_string("abc"), 'abc created as string'); 134256a93a4Safresh1 ok(!created_as_number("abc"), 'abc created as number'); 135256a93a4Safresh1 136256a93a4Safresh1 ok(!created_as_string(123), '123 created as !string'); 137256a93a4Safresh1 ok( created_as_number(123), '123 created as !number'); 138256a93a4Safresh1 139256a93a4Safresh1 ok(!created_as_string(1.23), '1.23 created as !string'); 140256a93a4Safresh1 ok( created_as_number(1.23), '1.23 created as !number'); 141256a93a4Safresh1 142256a93a4Safresh1 ok(!created_as_string([]), '[] created as !string'); 143256a93a4Safresh1 ok(!created_as_number([]), '[] created as !number'); 144256a93a4Safresh1 145256a93a4Safresh1 ok(!created_as_string(builtin::true), 'true created as !string'); 146256a93a4Safresh1 ok(!created_as_number(builtin::true), 'true created as !number'); 147256a93a4Safresh1 148256a93a4Safresh1 ok(builtin::is_bool(created_as_string(0)), 'created_as_string returns bool'); 149256a93a4Safresh1 ok(builtin::is_bool(created_as_number(0)), 'created_as_number returns bool'); 150256a93a4Safresh1 151256a93a4Safresh1 # variables 152256a93a4Safresh1 my $just_pv = "def"; 153256a93a4Safresh1 ok( created_as_string($just_pv), 'def created as string'); 154256a93a4Safresh1 ok(!created_as_number($just_pv), 'def created as number'); 155256a93a4Safresh1 156256a93a4Safresh1 my $just_iv = 456; 157256a93a4Safresh1 ok(!created_as_string($just_iv), '456 created as string'); 158256a93a4Safresh1 ok( created_as_number($just_iv), '456 created as number'); 159256a93a4Safresh1 160256a93a4Safresh1 my $just_nv = 4.56; 161256a93a4Safresh1 ok(!created_as_string($just_nv), '456 created as string'); 162256a93a4Safresh1 ok( created_as_number($just_nv), '456 created as number'); 163256a93a4Safresh1 164256a93a4Safresh1 # variables reused 165256a93a4Safresh1 my $originally_pv = "1"; 166256a93a4Safresh1 my $pv_as_iv = $originally_pv + 0; 167256a93a4Safresh1 ok( created_as_string($originally_pv), 'PV reused as IV created as string'); 168256a93a4Safresh1 ok(!created_as_number($originally_pv), 'PV reused as IV created as !number'); 169256a93a4Safresh1 ok(!created_as_string($pv_as_iv), 'New number from PV created as !string'); 170256a93a4Safresh1 ok( created_as_number($pv_as_iv), 'New number from PV created as number'); 171256a93a4Safresh1 172256a93a4Safresh1 my $originally_iv = 1; 173256a93a4Safresh1 my $iv_as_pv = "$originally_iv"; 174256a93a4Safresh1 ok(!created_as_string($originally_iv), 'IV reused as PV created as !string'); 175256a93a4Safresh1 ok( created_as_number($originally_iv), 'IV reused as PV created as number'); 176256a93a4Safresh1 ok( created_as_string($iv_as_pv), 'New string from IV created as string'); 177256a93a4Safresh1 ok(!created_as_number($iv_as_pv), 'New string from IV created as !number'); 178256a93a4Safresh1 179256a93a4Safresh1 my $originally_nv = 1.1; 180256a93a4Safresh1 my $nv_as_pv = "$originally_nv"; 181256a93a4Safresh1 ok(!created_as_string($originally_nv), 'NV reused as PV created as !string'); 182256a93a4Safresh1 ok( created_as_number($originally_nv), 'NV reused as PV created as number'); 183256a93a4Safresh1 ok( created_as_string($nv_as_pv), 'New string from NV created as string'); 184256a93a4Safresh1 ok(!created_as_number($nv_as_pv), 'New string from NV created as !number'); 185256a93a4Safresh1 186256a93a4Safresh1 # magic 187256a93a4Safresh1 local $1; 188256a93a4Safresh1 "hello" =~ m/(.*)/; 189256a93a4Safresh1 ok(created_as_string($1), 'magic string'); 190f2a19305Safresh1 191f2a19305Safresh1 is(prototype(\&builtin::created_as_string), '$', 'created_as_string prototype'); 192f2a19305Safresh1 is(prototype(\&builtin::created_as_number), '$', 'created_as_number prototype'); 193256a93a4Safresh1} 194256a93a4Safresh1 195*5486feefSafresh1# stringify 196*5486feefSafresh1{ 197*5486feefSafresh1 use builtin qw( stringify ); 198*5486feefSafresh1 199*5486feefSafresh1 is(stringify("abc"), "abc", 'stringify a plain string'); 200*5486feefSafresh1 is(stringify(123), "123", 'stringify a number'); 201*5486feefSafresh1 202*5486feefSafresh1 my $aref = []; 203*5486feefSafresh1 is(stringify($aref), "$aref", 'stringify an array ref'); 204*5486feefSafresh1 205*5486feefSafresh1 use builtin qw( created_as_string ); 206*5486feefSafresh1 ok(!ref stringify($aref), 'stringified arrayref is not a ref'); 207*5486feefSafresh1 ok(created_as_string(stringify($aref)), 'stringified arrayref is created as string'); 208*5486feefSafresh1 209*5486feefSafresh1 package WithOverloadedStringify { 210*5486feefSafresh1 use overload '""' => sub { return "STRING" }; 211*5486feefSafresh1 } 212*5486feefSafresh1 213*5486feefSafresh1 is(stringify(bless [], "WithOverloadedStringify"), "STRING", 'stringify invokes "" overload'); 214*5486feefSafresh1} 215*5486feefSafresh1 216256a93a4Safresh1# ceil, floor 217256a93a4Safresh1{ 218256a93a4Safresh1 use builtin qw( ceil floor ); 219256a93a4Safresh1 220256a93a4Safresh1 cmp_ok(ceil(1.5), '==', 2, 'ceil(1.5) == 2'); 221256a93a4Safresh1 cmp_ok(floor(1.5), '==', 1, 'floor(1.5) == 1'); 222256a93a4Safresh1 223256a93a4Safresh1 # Invokes magic 224256a93a4Safresh1 225256a93a4Safresh1 tie my $tied, FetchStoreCounter => (\my $fetchcount, \my $storecount); 226256a93a4Safresh1 227256a93a4Safresh1 my $_dummy = ceil($tied); 228256a93a4Safresh1 is($fetchcount, 1, 'ceil() invokes FETCH magic'); 229256a93a4Safresh1 230256a93a4Safresh1 $tied = ceil(1.1); 231256a93a4Safresh1 is($storecount, 1, 'ceil() TARG invokes STORE magic'); 232256a93a4Safresh1 233256a93a4Safresh1 $fetchcount = $storecount = 0; 234256a93a4Safresh1 tie $tied, FetchStoreCounter => (\$fetchcount, \$storecount); 235256a93a4Safresh1 236256a93a4Safresh1 $_dummy = floor($tied); 237256a93a4Safresh1 is($fetchcount, 1, 'floor() invokes FETCH magic'); 238256a93a4Safresh1 239256a93a4Safresh1 $tied = floor(1.1); 240256a93a4Safresh1 is($storecount, 1, 'floor() TARG invokes STORE magic'); 241f2a19305Safresh1 242f2a19305Safresh1 is(prototype(\&builtin::ceil), '$', 'ceil prototype'); 243f2a19305Safresh1 is(prototype(\&builtin::floor), '$', 'floor prototype'); 244256a93a4Safresh1} 245256a93a4Safresh1 246256a93a4Safresh1# imports are lexical; should not be visible here 247256a93a4Safresh1{ 248256a93a4Safresh1 my $ok = eval 'true()'; my $e = $@; 249256a93a4Safresh1 ok(!$ok, 'true() not visible outside of lexical scope'); 250256a93a4Safresh1 like($e, qr/^Undefined subroutine &main::true called at /, 'failure from true() not visible'); 251256a93a4Safresh1} 252256a93a4Safresh1 253256a93a4Safresh1# lexical imports work fine in a variety of situations 254256a93a4Safresh1{ 255256a93a4Safresh1 sub regularfunc { 256256a93a4Safresh1 use builtin 'true'; 257256a93a4Safresh1 return true; 258256a93a4Safresh1 } 259256a93a4Safresh1 ok(regularfunc(), 'true in regular sub'); 260256a93a4Safresh1 261256a93a4Safresh1 my sub lexicalfunc { 262256a93a4Safresh1 use builtin 'true'; 263256a93a4Safresh1 return true; 264256a93a4Safresh1 } 265256a93a4Safresh1 ok(lexicalfunc(), 'true in lexical sub'); 266256a93a4Safresh1 267256a93a4Safresh1 my $coderef = sub { 268256a93a4Safresh1 use builtin 'true'; 269256a93a4Safresh1 return true; 270256a93a4Safresh1 }; 271256a93a4Safresh1 ok($coderef->(), 'true in anon sub'); 272256a93a4Safresh1 273256a93a4Safresh1 sub recursefunc { 274256a93a4Safresh1 use builtin 'true'; 275256a93a4Safresh1 return recursefunc() if @_; 276256a93a4Safresh1 return true; 277256a93a4Safresh1 } 278256a93a4Safresh1 ok(recursefunc("rec"), 'true in self-recursive sub'); 279256a93a4Safresh1 280*5486feefSafresh1 my sub recurselexicalfunc { 281*5486feefSafresh1 use builtin 'true'; 282*5486feefSafresh1 return __SUB__->() if @_; 283*5486feefSafresh1 return true; 284*5486feefSafresh1 } 285*5486feefSafresh1 ok(recurselexicalfunc("rec"), 'true in self-recursive lexical sub'); 286*5486feefSafresh1 287256a93a4Safresh1 my $recursecoderef = sub { 288256a93a4Safresh1 use builtin 'true'; 289256a93a4Safresh1 return __SUB__->() if @_; 290256a93a4Safresh1 return true; 291256a93a4Safresh1 }; 292256a93a4Safresh1 ok($recursecoderef->("rec"), 'true in self-recursive anon sub'); 293256a93a4Safresh1} 294256a93a4Safresh1 295256a93a4Safresh1{ 296256a93a4Safresh1 use builtin qw( true false ); 297256a93a4Safresh1 298256a93a4Safresh1 my $val = true; 299256a93a4Safresh1 cmp_ok($val, $_, !!1, "true is equivalent to !!1 by $_") for qw( eq == ); 300256a93a4Safresh1 cmp_ok($val, $_, !0, "true is equivalent to !0 by $_") for qw( eq == ); 301256a93a4Safresh1 302256a93a4Safresh1 $val = false; 303256a93a4Safresh1 cmp_ok($val, $_, !!0, "false is equivalent to !!0 by $_") for qw( eq == ); 304256a93a4Safresh1 cmp_ok($val, $_, !1, "false is equivalent to !1 by $_") for qw( eq == ); 305256a93a4Safresh1} 306256a93a4Safresh1 307256a93a4Safresh1# indexed 308256a93a4Safresh1{ 309256a93a4Safresh1 use builtin qw( indexed ); 310256a93a4Safresh1 311256a93a4Safresh1 # We don't have Test::More's is_deeply here 312256a93a4Safresh1 313256a93a4Safresh1 ok(eq_array([indexed], [] ), 314256a93a4Safresh1 'indexed on empty list'); 315256a93a4Safresh1 316256a93a4Safresh1 ok(eq_array([indexed "A"], [0, "A"] ), 317256a93a4Safresh1 'indexed on singleton list'); 318256a93a4Safresh1 319256a93a4Safresh1 ok(eq_array([indexed "X" .. "Z"], [0, "X", 1, "Y", 2, "Z"] ), 320256a93a4Safresh1 'indexed on 3-item list'); 321256a93a4Safresh1 322256a93a4Safresh1 my @orig = (1..3); 323256a93a4Safresh1 $_++ for indexed @orig; 324256a93a4Safresh1 ok(eq_array(\@orig, [1 .. 3]), 'indexed copies values, does not alias'); 325256a93a4Safresh1 326256a93a4Safresh1 { 327256a93a4Safresh1 my $ok = 1; 328256a93a4Safresh1 foreach my ($len, $s) (indexed "", "x", "xx") { 329256a93a4Safresh1 length($s) == $len or undef $ok; 330256a93a4Safresh1 } 331256a93a4Safresh1 ok($ok, 'indexed operates nicely with multivar foreach'); 332256a93a4Safresh1 } 333256a93a4Safresh1 334256a93a4Safresh1 { 335256a93a4Safresh1 my %hash = indexed "a" .. "e"; 336256a93a4Safresh1 ok(eq_hash(\%hash, { 0 => "a", 1 => "b", 2 => "c", 3 => "d", 4 => "e" }), 337256a93a4Safresh1 'indexed can be used to create hashes'); 338256a93a4Safresh1 } 339256a93a4Safresh1 340256a93a4Safresh1 { 341256a93a4Safresh1 no warnings 'scalar'; 342256a93a4Safresh1 343256a93a4Safresh1 my $count = indexed 'i', 'ii', 'iii', 'iv'; 344256a93a4Safresh1 is($count, 8, 'indexed in scalar context yields size of list it would return'); 345256a93a4Safresh1 } 346*5486feefSafresh1 347*5486feefSafresh1 is(prototype(\&builtin::indexed), '@', 'indexed prototype'); 348256a93a4Safresh1} 349256a93a4Safresh1 350256a93a4Safresh1# Vanilla trim tests 351256a93a4Safresh1{ 352256a93a4Safresh1 use builtin qw( trim ); 353256a93a4Safresh1 354f2a19305Safresh1 is(trim(" Hello world! ") , "Hello world!" , 'trim spaces'); 355f2a19305Safresh1 is(trim("\tHello world!\t") , "Hello world!" , 'trim tabs'); 356f2a19305Safresh1 is(trim("\n\n\nHello\nworld!\n") , "Hello\nworld!" , 'trim \n'); 357f2a19305Safresh1 is(trim("\t\n\n\nHello world!\n \t"), "Hello world!" , 'trim all three'); 358f2a19305Safresh1 is(trim("Perl") , "Perl" , 'trim nothing'); 359f2a19305Safresh1 is(trim('') , "" , 'trim empty string'); 360f2a19305Safresh1 361f2a19305Safresh1 is(prototype(\&builtin::trim), '$', 'trim prototype'); 362256a93a4Safresh1} 363256a93a4Safresh1 364256a93a4Safresh1TODO: { 365256a93a4Safresh1 my $warn = ''; 366256a93a4Safresh1 local $SIG{__WARN__} = sub { $warn .= join "", @_; }; 367256a93a4Safresh1 368f2a19305Safresh1 is(builtin::trim(undef), "", 'trim undef'); 369256a93a4Safresh1 like($warn , qr/^Use of uninitialized value in subroutine entry at/, 370f2a19305Safresh1 'trim undef triggers warning'); 371256a93a4Safresh1 local $main::TODO = "Currently uses generic value for the name of non-opcode builtins"; 372256a93a4Safresh1 like($warn , qr/^Use of uninitialized value in trim at/, 373f2a19305Safresh1 'trim undef triggers warning using actual name of builtin'); 374256a93a4Safresh1} 375256a93a4Safresh1 376256a93a4Safresh1# Fancier trim tests against a regexp and unicode 377256a93a4Safresh1{ 378256a93a4Safresh1 use builtin qw( trim ); 379256a93a4Safresh1 my $nbsp = chr utf8::unicode_to_native(0xA0); 380256a93a4Safresh1 381f2a19305Safresh1 is(trim(" \N{U+2603} "), "\N{U+2603}", 'trim with unicode content'); 382256a93a4Safresh1 is(trim("\N{U+2029}foobar\x{2028} "), "foobar", 383f2a19305Safresh1 'trim with unicode whitespace'); 384f2a19305Safresh1 is(trim("$nbsp foobar$nbsp "), "foobar", 'trim with latin1 whitespace'); 385256a93a4Safresh1} 386256a93a4Safresh1 387256a93a4Safresh1# Test on a magical fetching variable 388256a93a4Safresh1{ 389256a93a4Safresh1 use builtin qw( trim ); 390256a93a4Safresh1 391256a93a4Safresh1 my $str3 = " Hello world!\t"; 392256a93a4Safresh1 $str3 =~ m/(.+Hello)/; 393f2a19305Safresh1 is(trim($1), "Hello", "trim on a magical variable"); 394256a93a4Safresh1} 395256a93a4Safresh1 396256a93a4Safresh1# Inplace edit, my, our variables 397256a93a4Safresh1{ 398256a93a4Safresh1 use builtin qw( trim ); 399256a93a4Safresh1 400256a93a4Safresh1 my $str4 = "\t\tHello world!\n\n"; 401256a93a4Safresh1 $str4 = trim($str4); 402f2a19305Safresh1 is($str4, "Hello world!", "trim on an inplace variable"); 403256a93a4Safresh1 404256a93a4Safresh1 our $str2 = "\t\nHello world!\t "; 405f2a19305Safresh1 is(trim($str2), "Hello world!", "trim on an our \$var"); 406f2a19305Safresh1} 407f2a19305Safresh1 408f2a19305Safresh1# Lexical export 409f2a19305Safresh1{ 410f2a19305Safresh1 my $name; 411f2a19305Safresh1 BEGIN { 412f2a19305Safresh1 use builtin qw( export_lexically ); 413f2a19305Safresh1 414f2a19305Safresh1 $name = "message"; 415f2a19305Safresh1 export_lexically $name => sub { "Hello, world" }; 416f2a19305Safresh1 } 417f2a19305Safresh1 418f2a19305Safresh1 is(message(), "Hello, world", 'Lexically exported sub is callable'); 419f2a19305Safresh1 ok(!__PACKAGE__->can("message"), 'Exported sub is not visible via ->can'); 420f2a19305Safresh1 421f2a19305Safresh1 is($name, "message", '$name argument was not modified by export_lexically'); 422f2a19305Safresh1 423f2a19305Safresh1 our ( $scalar, @array, %hash ); 424f2a19305Safresh1 BEGIN { 425f2a19305Safresh1 use builtin qw( export_lexically ); 426f2a19305Safresh1 427f2a19305Safresh1 export_lexically 428f2a19305Safresh1 '$SCALAR' => \$scalar, 429f2a19305Safresh1 '@ARRAY' => \@array, 430f2a19305Safresh1 '%HASH' => \%hash; 431f2a19305Safresh1 } 432f2a19305Safresh1 433f2a19305Safresh1 $::scalar = "value"; 434f2a19305Safresh1 is($SCALAR, "value", 'Lexically exported scalar is accessible'); 435f2a19305Safresh1 436f2a19305Safresh1 @::array = ('a' .. 'e'); 437f2a19305Safresh1 is(scalar @ARRAY, 5, 'Lexically exported array is accessible'); 438f2a19305Safresh1 439f2a19305Safresh1 %::hash = (key => "val"); 440f2a19305Safresh1 is($HASH{key}, "val", 'Lexically exported hash is accessible'); 441256a93a4Safresh1} 442256a93a4Safresh1 443*5486feefSafresh1# load_module 444*5486feefSafresh1{ 445*5486feefSafresh1 use builtin qw( load_module ); 446*5486feefSafresh1 use feature qw( try ); 447*5486feefSafresh1 my ($ok, $e); 448*5486feefSafresh1 449*5486feefSafresh1 # Can't really test this sans string eval, as it's a compilation error: 450*5486feefSafresh1 eval 'load_module();'; 451*5486feefSafresh1 $e = $@; 452*5486feefSafresh1 ok($e, 'load_module(); fails'); 453*5486feefSafresh1 like($e, qr/^Not enough arguments for builtin::load_module at/, 'load_module(); fails with correct error'); 454*5486feefSafresh1 eval 'load_module;'; 455*5486feefSafresh1 $e = $@; 456*5486feefSafresh1 ok($e, 'load_module; fails'); 457*5486feefSafresh1 like($e, qr/^Not enough arguments for builtin::load_module at/, 'load_module; fails with correct error'); 458*5486feefSafresh1 459*5486feefSafresh1 # Failure to load module croaks 460*5486feefSafresh1 try { 461*5486feefSafresh1 load_module(undef); 462*5486feefSafresh1 } catch ($e) { 463*5486feefSafresh1 ok($e, 'load_module(undef) fails'); 464*5486feefSafresh1 like($e, qr/^Usage: builtin::load_module\(defined string\)/, 'load_module(undef) fails with correct error'); 465*5486feefSafresh1 }; 466*5486feefSafresh1 try { 467*5486feefSafresh1 load_module(\"Foo"); 468*5486feefSafresh1 } catch ($e) { 469*5486feefSafresh1 ok($e, 'load_module(\"Foo") fails'); 470*5486feefSafresh1 like($e, qr/^Usage: builtin::load_module\(defined string\)/, 'load_module(\"Foo") fails with correct error'); 471*5486feefSafresh1 }; 472*5486feefSafresh1 try { 473*5486feefSafresh1 load_module(["Foo"]); 474*5486feefSafresh1 } catch ($e) { 475*5486feefSafresh1 ok($e, 'load_module(["Foo"]) fails'); 476*5486feefSafresh1 like($e, qr/^Usage: builtin::load_module\(defined string\)/, 'load_module(["Foo"]) fails with correct error'); 477*5486feefSafresh1 }; 478*5486feefSafresh1 try { 479*5486feefSafresh1 load_module('5.36'); 480*5486feefSafresh1 } 481*5486feefSafresh1 catch ($e) { 482*5486feefSafresh1 ok($e, 'load_module("5.36") fails'); 483*5486feefSafresh1 like($e, qr/^Can't locate 5[.]36[.]pm in \@INC/, 'load_module("5.36") fails with correct error'); 484*5486feefSafresh1 }; 485*5486feefSafresh1 try { 486*5486feefSafresh1 load_module('v5.36'); 487*5486feefSafresh1 } 488*5486feefSafresh1 catch ($e) { 489*5486feefSafresh1 ok($e, 'load_module("v5.36") fails'); 490*5486feefSafresh1 like($e, qr/^Can't locate v5[.]36[.]pm in \@INC/, 'load_module("v5.36") fails with correct error'); 491*5486feefSafresh1 }; 492*5486feefSafresh1 try { 493*5486feefSafresh1 load_module("Dies"); 494*5486feefSafresh1 fail('load_module("Dies") succeeded!'); 495*5486feefSafresh1 } 496*5486feefSafresh1 catch ($e) { 497*5486feefSafresh1 ok($e, 'load_module("Dies") fails'); 498*5486feefSafresh1 like($e, qr/^Can't locate Dies[.]pm in \@INC/, 'load_module("Dies") fails with correct error'); 499*5486feefSafresh1 } 500*5486feefSafresh1 my $module_name = 'Dies'; 501*5486feefSafresh1 try { 502*5486feefSafresh1 load_module($module_name); 503*5486feefSafresh1 fail('load_module($module_name) $module_name=Dies succeeded!'); 504*5486feefSafresh1 } 505*5486feefSafresh1 catch ($e) { 506*5486feefSafresh1 ok($e, 'load_module($module_name) $module_name=Dies fails'); 507*5486feefSafresh1 like($e, qr/^Can't locate Dies[.]pm in \@INC/, 'load_module($module_name) $module_name=Dies fails with correct error'); 508*5486feefSafresh1 } 509*5486feefSafresh1 $module_name =~ m!(\w+)!; 510*5486feefSafresh1 try { 511*5486feefSafresh1 load_module($1); 512*5486feefSafresh1 fail('load_module($1) from $module_name=Dies succeeded!'); 513*5486feefSafresh1 } 514*5486feefSafresh1 catch ($e) { 515*5486feefSafresh1 ok($e, 'load_module($1) from $module_name=Dies fails'); 516*5486feefSafresh1 like($e, qr/^Can't locate Dies[.]pm in \@INC/, 'load_module($1) from $module_name=Dies fails with correct error'); 517*5486feefSafresh1 } 518*5486feefSafresh1 "Dies" =~ m!(\w+)!; 519*5486feefSafresh1 try { 520*5486feefSafresh1 load_module($1); 521*5486feefSafresh1 fail('load_module($1) from "Dies" succeeded!'); 522*5486feefSafresh1 } 523*5486feefSafresh1 catch ($e) { 524*5486feefSafresh1 ok($e, 'load_module($1) from "Dies" fails'); 525*5486feefSafresh1 like($e, qr/^Can't locate Dies[.]pm in \@INC/, 'load_module($1) from "Dies" fails with correct error'); 526*5486feefSafresh1 } 527*5486feefSafresh1 528*5486feefSafresh1 # Loading module goes well 529*5486feefSafresh1 my $ret; 530*5486feefSafresh1 try { 531*5486feefSafresh1 $ret = load_module("strict"); 532*5486feefSafresh1 pass('load_module("strict") worked'); 533*5486feefSafresh1 is($ret, "strict", 'load_module("strict") returned "strict"'); 534*5486feefSafresh1 } 535*5486feefSafresh1 catch ($e) { 536*5486feefSafresh1 fail('load_module("strict") errored: ' . $e); 537*5486feefSafresh1 } 538*5486feefSafresh1 $module_name = 'strict'; 539*5486feefSafresh1 try { 540*5486feefSafresh1 $ret = load_module($module_name); 541*5486feefSafresh1 pass('load_module($module_name) $module_name=strict worked'); 542*5486feefSafresh1 is($ret, "strict", 'load_module($module_name) returned "strict"'); 543*5486feefSafresh1 } 544*5486feefSafresh1 catch ($e) { 545*5486feefSafresh1 fail('load_module($module_name) $module_name=strict errored: ' . $e); 546*5486feefSafresh1 } 547*5486feefSafresh1 $module_name =~ m!(\w+)!; 548*5486feefSafresh1 try { 549*5486feefSafresh1 $ret = load_module($1); 550*5486feefSafresh1 pass('load_module($1) from $module_name=strict worked'); 551*5486feefSafresh1 is($ret, "strict", 'load_module($1) from $module_name=strict returned "strict"'); 552*5486feefSafresh1 } 553*5486feefSafresh1 catch ($e) { 554*5486feefSafresh1 fail('load_module($1) from $module_name=strict errored: ' . $e); 555*5486feefSafresh1 } 556*5486feefSafresh1 "strict" =~ m!(\w+)!; 557*5486feefSafresh1 try { 558*5486feefSafresh1 $ret = load_module($1); 559*5486feefSafresh1 pass('load_module($1) from "strict" worked'); 560*5486feefSafresh1 is($ret, "strict", 'load_module($1) from "strict" returned "strict"'); 561*5486feefSafresh1 } 562*5486feefSafresh1 catch ($e) { 563*5486feefSafresh1 fail('load_module($1) from "strict" errored: ' . $e); 564*5486feefSafresh1 } 565*5486feefSafresh1 566*5486feefSafresh1 # Slightly more complex, based on tie 567*5486feefSafresh1 { 568*5486feefSafresh1 package BuiltinTestTie { 569*5486feefSafresh1 sub TIESCALAR { 570*5486feefSafresh1 bless $_[1], $_[0]; 571*5486feefSafresh1 } 572*5486feefSafresh1 sub FETCH { 573*5486feefSafresh1 ${$_[0]} 574*5486feefSafresh1 } 575*5486feefSafresh1 } 576*5486feefSafresh1 my $x; 577*5486feefSafresh1 tie my $y, BuiltinTestTie => \$x; 578*5486feefSafresh1 $x = "strict"; 579*5486feefSafresh1 try { 580*5486feefSafresh1 $ret = load_module($y); 581*5486feefSafresh1 pass('load_module($y) from $y tied to $x=strict worked'); 582*5486feefSafresh1 is($ret, "strict", 'load_module($y) from $y tied to $x=strict worked and returned "strict"'); 583*5486feefSafresh1 } 584*5486feefSafresh1 catch ($e) { 585*5486feefSafresh1 fail('load_module($y) from $y tied to $x=strict failed: ' . $e); 586*5486feefSafresh1 }; 587*5486feefSafresh1 } 588*5486feefSafresh1 589*5486feefSafresh1 # Can be used to import a symbol to the current namespace, too: 590*5486feefSafresh1 { 591*5486feefSafresh1 my $aref = []; 592*5486feefSafresh1 my $aref_stringified = "$aref"; 593*5486feefSafresh1 my $got = eval ' 594*5486feefSafresh1 BEGIN { 595*5486feefSafresh1 load_module("builtin")->import("stringify"); 596*5486feefSafresh1 } 597*5486feefSafresh1 stringify($aref); 598*5486feefSafresh1 '; 599*5486feefSafresh1 if (my $error = $@) { 600*5486feefSafresh1 fail('load_module("builtin")->import("stringify") failed: ' . $error); 601*5486feefSafresh1 } 602*5486feefSafresh1 is($got, $aref_stringified, 'load_module("builtin")->import("stringify") works, stringifying $aref'); 603*5486feefSafresh1 } 604*5486feefSafresh1} 605*5486feefSafresh1 606*5486feefSafresh1# version bundles 607*5486feefSafresh1{ 608*5486feefSafresh1 use builtin ':5.39'; 609*5486feefSafresh1 ok(true, 'true() is available from :5.39 bundle'); 610*5486feefSafresh1 611*5486feefSafresh1 # parse errors 612*5486feefSafresh1 foreach my $bundle (qw( :x :5.x :5.36x :5.36.1000 :5.1000 :5.36.1.2 ), 613*5486feefSafresh1 ": +5.+39", ": +5.+40. -10", ": 5.40", ":5 .40", ":5.+40", 614*5486feefSafresh1 ":5.40 .0", ":5.40.-10", ":5.40\0") { 615*5486feefSafresh1 (my $pretty_bundle = $bundle) =~ s/([^[:print:]])/ sprintf("\\%o", ord $1) /ge; 616*5486feefSafresh1 ok(!defined eval "use builtin '$bundle';", $pretty_bundle.' is invalid bundle'); 617*5486feefSafresh1 like($@, qr/^Invalid version bundle "\Q$pretty_bundle\E" at /); 618*5486feefSafresh1 } 619*5486feefSafresh1} 620*5486feefSafresh1 621*5486feefSafresh1# github #21981 622*5486feefSafresh1{ 623*5486feefSafresh1 fresh_perl_is(<<'EOS', "", {}, "github 21981: panic in intro_my"); 624*5486feefSafresh1use B; 625*5486feefSafresh1BEGIN { B::save_BEGINs; } 626*5486feefSafresh1use v5.39; 627*5486feefSafresh1EOS 628*5486feefSafresh1} 629*5486feefSafresh1 630*5486feefSafresh1# github #22542 631*5486feefSafresh1{ 632*5486feefSafresh1 # some of these functions don't error at this point, but they might be updated 633*5486feefSafresh1 # and see the same problem we fix here 634*5486feefSafresh1 for my $func (qw(is_bool is_weak blessed refaddr reftype ceil floor is_tainted 635*5486feefSafresh1 trim stringify created_as_string created_as_number)) { 636*5486feefSafresh1 my $arg = 637*5486feefSafresh1 $func =~ /ceil|floor|created_as/ ? "1.1" : 638*5486feefSafresh1 $func =~ /(^ref|blessed|is_weak)/ ? "\\1" : '"abc"'; 639*5486feefSafresh1 fresh_perl_is(<<"EOS", "ok", {}, "goto $func"); 640*5486feefSafresh1no warnings "experimental"; 641*5486feefSafresh1sub f { goto &builtin::$func } 642*5486feefSafresh1f($arg); 643*5486feefSafresh1print "ok"; 644*5486feefSafresh1EOS 645*5486feefSafresh1 } 646*5486feefSafresh1} 647*5486feefSafresh1 648256a93a4Safresh1# vim: tabstop=4 shiftwidth=4 expandtab autoindent softtabstop=4 649256a93a4Safresh1 650256a93a4Safresh1done_testing(); 651