summaryrefslogtreecommitdiff
path: root/dist/Attribute-Handlers
diff options
context:
space:
mode:
authorGraham Knop <haarg@haarg.org>2022-03-01 08:31:03 +0100
committerYves Orton <demerphq@gmail.com>2022-03-01 16:20:36 +0100
commitf0ef35deb0072805b68cef82ebe28739f67ca79a (patch)
treedae12b8e86de697f54752069dc7fe8fa6b11e8d9 /dist/Attribute-Handlers
parent5fd455724334701f8b57422da66c641df3c87963 (diff)
downloadperl-f0ef35deb0072805b68cef82ebe28739f67ca79a.tar.gz
wrap any existing import in Attribute::Handlers' injected import
Some modules using Attribute::Handlers autotie feature have their own import method. When injecting an import method, attempt to wrap anything that exists, either in the class directly or in a parent class. We can't detect parent classes at injection time, because @ISA may change, and this is actually common since users of Exporter will add it as a parent class at module runtime, while Attribute::Handlers injection would happen first during compilation. A better approach could involve using next::can from mro, but that also requires Sub::Util::set_subname, and Attribute::Handlers is dual life and currently supports 5.6.
Diffstat (limited to 'dist/Attribute-Handlers')
-rw-r--r--dist/Attribute-Handlers/lib/Attribute/Handlers.pm27
1 files changed, 20 insertions, 7 deletions
diff --git a/dist/Attribute-Handlers/lib/Attribute/Handlers.pm b/dist/Attribute-Handlers/lib/Attribute/Handlers.pm
index 6de6ae987c..21f657dcb9 100644
--- a/dist/Attribute-Handlers/lib/Attribute/Handlers.pm
+++ b/dist/Attribute-Handlers/lib/Attribute/Handlers.pm
@@ -88,13 +88,26 @@ sub import {
if ($attr =~ /\A__CALLER__::/) {
no strict 'refs';
- *{ caller . '::import' } = sub {
- my $caller = caller;
- my $full_attr = $attr;
- $full_attr =~ s/__CALLER__/$caller/;
- eval qq{ sub $full_attr $code 1; }
- or die "Internal error: $@";
-
+ my $add_import = caller;
+ my $next = defined &{ $add_import . '::import' } && \&{ $add_import . '::import' };
+ *{ $add_import . '::import' } = sub {
+ my $caller = caller;
+ my $full_attr = $attr;
+ $full_attr =~ s/__CALLER__/$caller/;
+ eval qq{ sub $full_attr $code 1; }
+ or die "Internal error: $@";
+
+ goto &$next
+ if $next;
+ my $uni = defined &UNIVERSAL::import && \&UNIVERSAL::import;
+ for my $isa (@{ $add_import . '::ISA' }) {
+ if (my $import = $isa->can('import')) {
+ goto &$import
+ if $import != $uni;
+ }
+ }
+ goto &$uni
+ if $uni;
};
}
else {