-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathDelegator.pm
48 lines (42 loc) · 1.13 KB
/
Delegator.pm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
# Copyright (c) 2001-2012 bivio Software, Inc. All rights reserved.
# $Id$
package Bivio::Delegator;
use strict;
use Bivio::Base 'Bivio.UNIVERSAL';
our($AUTOLOAD);
our($_PREV_AUTOLOAD) = '';
my($_CL) = b_use('IO.ClassLoader');
my($_IDI) = __PACKAGE__->instance_data_index;
my($_MAP) = {};
sub AUTOLOAD {
my($proto) = shift;
my($method) = $AUTOLOAD =~ /([^:]+)$/;
return
if $method eq 'DESTROY';
die($AUTOLOAD, ': infinite delegation loop')
if $AUTOLOAD eq $_PREV_AUTOLOAD;
local($_PREV_AUTOLOAD) = $AUTOLOAD;
return (
ref($proto) ? $proto->[$_IDI]->{delegate}
: $proto->internal_delegate_package
)->$method(@_);
}
sub b_can {
my($proto, $method) = @_;
return $proto->internal_delegate_package->can($method)
|| $proto->SUPER::b_can($method)
? 1 : 0;
}
sub internal_delegate_package {
my($proto) = @_;
return $_MAP->{$proto} ||= $_CL->delegate_require($proto);
}
sub new {
my($proto, @args) = @_;
my($self) = $proto->SUPER::new;
$self->[$_IDI] = {
delegate => ref($self)->internal_delegate_package->new(@args),
};
return $self;
}
1;