M
Matthew Braid
Hi all,
Unfortunately this is another one that I can't reproduce in a small
script, but maybe the description will trigger something from someone....
In the system I'm writing library functions can be extended like so:
package Core;
use base qw/Exporter/;
{
no strict 'refs';
sub import { # This code severely chopped down to basics
# Redefine import so that overrides are noticed even
# in places where the original function has already been
# imported
my $class = shift;
my @funcs = @_;
my ($caller) = caller();
for my $f (@funcs) {
*{"$caller\::$f"} = sub {goto &{"$class\::$f"}};
}
}
}
sub foo {
print "Core::foo GOT (@_)\n";
}
# --- In a file not so very far away...
package Extension;
BEGIN {
require Core;
my $old = \&Core::foo;
sub foo {
print "Ext::foo GOT (@_)\n";
goto &$old;
}
*Core::foo = \&foo;
}
Of course, extensions can be extended etc etc. The problem I've run in
to is the goto bit - it seems that if the level of 'extension' is too
high, the destination of the goto ends up with @_ full of undefs - right
number of args, wrong values. Even stranger is that if I was expecting a
hashref keying some objects and I have:
$arg->{ObjectName}->method;
instead of the usual "Can't call method "method" on an undefined value"
error, the script is terminated with a signal 11.
Oddly enough, if I throw in the otherwise useless line:
@_ = @_;
just before the goto, suddenly it works again.
So there is a workaround - either the odd '@_ = @_' thing which looks
too much like a smiley or instead of goto& just simply call the old
function as in $old->(@_), but I'm thinking the destruction of @_ and
the terminate on signal 11 thing may be a bug in perl itself.
Any ideas?
MB
Unfortunately this is another one that I can't reproduce in a small
script, but maybe the description will trigger something from someone....
In the system I'm writing library functions can be extended like so:
package Core;
use base qw/Exporter/;
{
no strict 'refs';
sub import { # This code severely chopped down to basics
# Redefine import so that overrides are noticed even
# in places where the original function has already been
# imported
my $class = shift;
my @funcs = @_;
my ($caller) = caller();
for my $f (@funcs) {
*{"$caller\::$f"} = sub {goto &{"$class\::$f"}};
}
}
}
sub foo {
print "Core::foo GOT (@_)\n";
}
# --- In a file not so very far away...
package Extension;
BEGIN {
require Core;
my $old = \&Core::foo;
sub foo {
print "Ext::foo GOT (@_)\n";
goto &$old;
}
*Core::foo = \&foo;
}
Of course, extensions can be extended etc etc. The problem I've run in
to is the goto bit - it seems that if the level of 'extension' is too
high, the destination of the goto ends up with @_ full of undefs - right
number of args, wrong values. Even stranger is that if I was expecting a
hashref keying some objects and I have:
$arg->{ObjectName}->method;
instead of the usual "Can't call method "method" on an undefined value"
error, the script is terminated with a signal 11.
Oddly enough, if I throw in the otherwise useless line:
@_ = @_;
just before the goto, suddenly it works again.
So there is a workaround - either the odd '@_ = @_' thing which looks
too much like a smiley or instead of goto& just simply call the old
function as in $old->(@_), but I'm thinking the destruction of @_ and
the terminate on signal 11 thing may be a bug in perl itself.
Any ideas?
MB