Date: | Thu, 30 May 2019 10:19:19 -0600 |
To: | undisclosed-recipients:; |
From: | chazmcgarvey [...] brokenzipper.com |
From 7fde72d862855a9905b241707283ed2c9f871118 Mon Sep 17 00:00:00 2001
From: Charles McGarvey <chazmcgarvey@brokenzipper.com>
Date: Wed, 29 May 2019 22:21:41 -0600
Subject: [PATCH] Work around gv_fetchmeth_pvn bug in older perls
To: bug-SUPER@rt.cpan.org
See: https://github.com/chromatic/SUPER/pull/1
This allows main->SUPER::... to work when SUPER.pm is loaded. The perl
bug breaking this was fixed in commit 3c104e59, released with 5.17.4.
---
lib/SUPER.pm | 15 ++++++++++++++
t/pseudoclass_syntax.t | 44 ++++++++++++++++++++++++++++++++++++++++++
2 files changed, 59 insertions(+)
create mode 100644 t/pseudoclass_syntax.t
diff --git a/lib/SUPER.pm b/lib/SUPER.pm
index 57b0062..6239298 100644
--- a/lib/SUPER.pm
+++ b/lib/SUPER.pm
@@ -42,6 +42,21 @@ use Carp;
use Scalar::Util 'blessed';
use Sub::Identify ();
+BEGIN {
+ # Due to a perl bug (fixed in v5.17.4, commit 3c104e59), if SUPER.pm is
+ # loaded, perl can no longer find methods on parent when:
+ # 1) the invocant is "main" (or isa "main")
+ # 2) using the SUPER pseudo-class syntax (i.e. "main"->SUPER::...)
+ # We work around that bug by handling ->SUPER::... ourselves.
+ if ($] < 5.017004)
+ {
+ no strict 'refs';
+ *{"SUPER::AUTOLOAD"} = sub {
+ goto &UNIVERSAL::SUPER;
+ };
+ }
+}
+
# no need to use Exporter
sub import
{
diff --git a/t/pseudoclass_syntax.t b/t/pseudoclass_syntax.t
new file mode 100644
index 0000000..cc3a1a5
--- /dev/null
+++ b/t/pseudoclass_syntax.t
@@ -0,0 +1,44 @@
+#!perl
+use strict;
+use warnings;
+
+# Test that the pseudo-class syntax still works despite having SUPER.pm loaded.
+
+use SUPER;
+use Test::More tests => 6;
+
+package MyBase;
+
+Test::More->import();
+
+sub new { bless {}, shift }
+
+sub foo
+{
+ my $self = shift;
+ if (ref $self) {
+ isa_ok( $self, "main" );
+ }
+ else {
+ is( $self, "main" ); # isa_ok($str) doesn't work on older Test::More
+ }
+ is( $_[0], 123, "Arguments passed OK" );
+}
+
+package main;
+
+Test::More->import();
+@main::ISA = 'MyBase';
+
+sub foo
+{
+ my $self = shift;
+ $self->SUPER::foo(@_);
+}
+
+eval { main->foo(123) };
+is( $@, '', 'Can use pseudo-class main->SUPER::method syntax' );
+
+my $m = main->new();
+eval { $m->foo(123) };
+is( $@, '', 'Can use pseudo-class $isa_main->SUPER::method syntax' );
--
2.21.0