[perl-Glib/gio-support: 6/12] [gio] Adjust the dynamic method resolution for multiple inheritance
- From: Torsten Schönfeld <tsch src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [perl-Glib/gio-support: 6/12] [gio] Adjust the dynamic method resolution for multiple inheritance
- Date: Mon, 12 Apr 2010 21:12:25 +0000 (UTC)
commit f43bb77ac7e941e7bf79145b8b03f7ea74512b7a
Author: Torsten Schönfeld <kaffeetisch gmx de>
Date: Wed Mar 3 00:04:17 2010 +0100
[gio] Adjust the dynamic method resolution for multiple inheritance
lib/Glib.pm | 69 ++++++++++++++++++++++++++++++++++++++++++++++------------
1 files changed, 54 insertions(+), 15 deletions(-)
---
diff --git a/lib/Glib.pm b/lib/Glib.pm
index c27e8ac..047d57f 100644
--- a/lib/Glib.pm
+++ b/lib/Glib.pm
@@ -219,17 +219,22 @@ package Glib::Object::_Introspection;
use strict;
-sub find_registered_namespace {
+sub find_registered_ancestors {
my ($class, $namespace) = @_;
- # replace the prefix for unregistered types
- while ($namespace =~ m/^Glib::Object::_Unregistered::\w+/) {
+ my @ancestors = ($namespace);
+ {
no strict 'refs';
my @parents = @{$namespace . '::ISA'};
- $namespace = $parents[-1];
+ foreach my $parent (@parents) {
+ push @ancestors, __PACKAGE__->find_registered_ancestors($parent);
+ }
}
- return $namespace;
+ my @registered_ancestors =
+ grep { !m/^Glib::Object::_Unregistered::/ } @ancestors;
+
+ return @registered_ancestors;
}
package Glib::IO;
@@ -249,20 +254,54 @@ sub AUTOLOAD {
# 'namespace::method' or just 'method'
if ($symbol =~ m/(?:(.+)::)?(.+)/) {
- my $namespace = $1;
- my $method = $2;
-
- if (defined $namespace) {
- $namespace = Glib::Object::_Introspection->find_registered_namespace (
- $namespace);
+ my $symbol_namespace = $1;
+ my $symbol_method = $2;
+
+ # FIXME: we are effectively reimplementing method resolution here.
+ # consider ditching the AUTOLOAD clutch in favor of just installing sub
+ # stubs in the correct places for all methods and functions.
+ my @namespace_candidates = ();
+ if (defined $symbol_namespace) {
+ @namespace_candidates =
+ Glib::Object::_Introspection->find_registered_ancestors (
+ $symbol_namespace);
# strip off the normal prefix
- $namespace =~ s/^${PACKAGE}(?:::)?//;
- $namespace = undef if $namespace eq '';
+ foreach my $namespace (@namespace_candidates) {
+ # alter the array in-place
+ $namespace =~ s/^${PACKAGE}(?:::)?//;
+ $namespace = undef if $namespace eq '';
+ }
+ }
+
+ if (! namespace_candidates) {
+ @namespace_candidates = (undef);
+ }
+
+ # warn "namespace candidates for $symbol: (@namespace_candidates)\n";
+
+ my @errors;
+ my @results;
+ foreach my $namespace (@namespace_candidates) {
+ @results = eval {
+ Glib::Object::_Introspection->invoke(
+ $BASENAME, $namespace, $symbol_method, @args); };
+ if ($@) {
+ if ($ ->isa ('Glib::Error')) {
+ croak $@;
+ }
+ push @errors, $@;
+ } else {
+ @errors = ();
+ last;
+ }
+ }
+
+ if (! results && @errors) {
+ croak "Invalid invocation of $symbol:\n ", join "\n ", @errors;
}
- return Glib::Object::_Introspection->invoke(
- $BASENAME, $namespace, $method, @args);
+ return wantarray ? @results : $results[0];
}
croak "Invalid invocation: Cannot handle $symbol";
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]