BEGIN {
chdir 't' if -d 't';
- @INC = qw(. ../lib lib);
- require "test.pl";
+ @INC = qw(. ../lib lib ../dist/base/lib);
+ require "./test.pl";
}
use strict;
no warnings 'once';
-plan(tests => 142);
+plan(tests => 150);
@A::ISA = 'B';
@B::ISA = 'C';
is(A->eee(), "new B: In A::eee, 4"); # We get a correct $autoload
is(A->eee(), "new B: In A::eee, 4"); # Which sticks
-{
- no strict 'refs';
- no warnings 'deprecated';
- # this test added due to bug discovery (in 5.004_04, fb73857aa0bfa8ed)
- # Possibly kill this test now that defined @::array is finally properly
- # deprecated?
- is(defined(@{"unknown_package::ISA"}) ? "defined" : "undefined", "undefined");
-}
-
# test that failed subroutine calls don't affect method calls
{
package A1;
'SUPER inside moved package respects method changes';
}
+package foo120694 {
+ BEGIN { our @ISA = qw(bar120694) }
+
+ sub AUTOLOAD {
+ my $self = shift;
+ local our $recursive = $recursive;
+ return "recursive" if $recursive++;
+ return if our $AUTOLOAD eq 'DESTROY';
+ $AUTOLOAD = "SUPER:" . substr $AUTOLOAD, rindex($AUTOLOAD, ':');
+ return $self->$AUTOLOAD(@_);
+ }
+}
+package bar120694 {
+ sub AUTOLOAD {
+ return "xyzzy";
+ }
+}
+is bless( [] => "foo120694" )->plugh, 'xyzzy',
+ '->SUPER::method autoloading uses parent of current pkg';
+
+
# failed method call or UNIVERSAL::can() should not autovivify packages
is( $::{"Foo::"} || "none", "none"); # sanity check 1
is( $::{"Foo::"} || "none", "none"); # sanity check 2
{
fresh_perl_is(<<EOT,
package UNIVERSAL; sub AUTOLOAD { my \$c = shift; print "\$c \$AUTOLOAD\\n" }
+sub DESTROY {} # prevent AUTOLOAD being called on DESTROY
package Xyz;
package main; Foo->$meth->[0]();
EOT
*NulTest::AUTOLOAD = sub { our $AUTOLOAD; return $AUTOLOAD };
- like(NulTest->${ \"nul\0test" }, "nul\0test", "AUTOLOAD is nul-clean");
+ like(NulTest->${ \"nul\0test" }, qr/nul\0test/, "AUTOLOAD is nul-clean");
}
{ bless {}, "NoSub"; }
}
+{
+ # [perl #124387]
+ my $autoloaded;
+ package AutoloadDestroy;
+ sub AUTOLOAD { $autoloaded = 1 }
+ package main;
+ bless {}, "AutoloadDestroy";
+ ok($autoloaded, "AUTOLOAD called for DESTROY");
+
+ # 127494 - AUTOLOAD for DESTROY was called without setting $AUTOLOAD
+ my %methods;
+ package AutoloadDestroy2;
+ sub AUTOLOAD {
+ our $AUTOLOAD;
+ (my $method = $AUTOLOAD) =~ s/.*:://;
+ ++$methods{$method};
+ }
+ package main;
+ # this cached AUTOLOAD as the DESTROY method
+ bless {}, "AutoloadDestroy2";
+ %methods = ();
+ my $o = bless {}, "AutoloadDestroy2";
+ # this sets $AUTOLOAD to "AutoloadDestroy2::foo"
+ $o->foo;
+ # this would call AUTOLOAD without setting $AUTOLOAD
+ undef $o;
+ ok($methods{DESTROY}, "\$AUTOLOAD set correctly for DESTROY");
+}
+
eval { () = 3; new {} };
like $@,
qr/^Can't call method "new" without a package or object reference/,
{ no strict; @{"3foo::ISA"} = "CORE"; }
is "3foo"->uc, '3FOO', '"3foo"->uc (autobox style!)';
+# *foo vs (\*foo)
+sub myclass::squeak { 'eek' }
+eval { *myclass->squeak };
+like $@,
+ qr/^Can't call method "squeak" without a package or object reference/,
+ 'method call on typeglob ignores package';
+eval { (\*myclass)->squeak };
+like $@,
+ qr/^Can't call method "squeak" on unblessed reference/,
+ 'method call on \*typeglob';
+*stdout2 = *STDOUT; # stdout2 now stringifies as *main::STDOUT
+sub IO::Handle::self { $_[0] }
+# This used to stringify the glob:
+is *stdout2->self, (\*stdout2)->self,
+ '*glob->method is equiv to (\*glob)->method';
+sub { $_[0] = *STDOUT; is $_[0]->self, \$::h{k}, '$pvlv_glob->method' }
+ ->($::h{k});
+
# Test that PL_stashcache doesn't change the resolution behaviour for file
# handles and package names.
SKIP: {
seek DATA, $data_start, Fcntl::SEEK_SET() or die $!;
is(Colour::H1->getline(), <DATA>, 'read from a file');
- is(C3::H1->getline(), 'method in C3::H1', 'intial resolution is a method');
+ is(C3::H1->getline(), 'method in C3::H1', 'initial resolution is a method');
*Copy:: = \*C3::;
*C3:: = \*Colour::;
'restoring the stash returns to a method');
}
+# RT #123619 constant class name should be read-only
+
+{
+ sub RT123619::f { chop $_[0] }
+ eval { 'RT123619'->f(); };
+ like ($@, qr/Modification of a read-only value attempted/, 'RT #123619');
+}
+
+{
+ # RT #126042 &{1==1} * &{1==1} would crash
+
+ # pp_entersub and pp_method_named cooperate to prevent calls to an
+ # undefined import() or unimport() method from croaking.
+ # If pp_method_named can't find the method it pushes &PL_sv_yes, and
+ # pp_entersub checks for that specific SV to avoid croaking.
+ # Ideally they wouldn't use that hack but...
+ # Unfortunately pp_entersub's handling of that case is broken in scalar context.
+
+ # Rather than using the test case from the ticket, since &{1==1}
+ # isn't documented (and may not be supported in future perls) test
+ # calls to undefined import method, which also crashes.
+ fresh_perl_is('Unknown->import() * Unknown->unimport(); print "ok\n"', "ok\n", {},
+ "check unknown import() methods don't corrupt the stack");
+}
+
__END__
#FF9900
#F78C08