Bivio::Type::EnumDelegator
# Copyright (c) 2004-2007 bivio Software, Inc. All Rights Reserved.
# $Id$
package Bivio::Type::EnumDelegator;
use strict;
use Bivio::Base 'Type.Enum';
our($AUTOLOAD);
our($_PREV_AUTOLOAD) = '';
my($_MAP) = {};
my($_CL) = b_use('IO.ClassLoader');
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;
my($delegator) = $proto->package_name;
my($delegate) = $delegator->internal_delegate_package;
# can() returns a reference to the method to invoke
# use this so delegates can be subclassed
my($dispatch) = $delegate->can($method);
return !$dispatch
? $proto->can($method)
? $proto->$method(@_)
: b_die($method, ': method not found in ', $delegator, ' or ', $delegate)
: ref($proto)
? $dispatch->($proto, @_)
: $delegate->$method(@_);
}
sub compile {
my($proto, $values) = @_;
return $proto->SUPER::compile(
$values || $_CL->delegate_require($proto)->get_delegate_info,
);
}
sub internal_delegate_package {
my($proto) = @_;
my($delegator) = $proto->package_name;
($_MAP->{$delegator} = $_CL->delegate_require($delegator))
->internal_set_delegator_package($delegator)
unless $_MAP->{$delegator};
return $_MAP->{$delegator};
}
sub is_continuous {
return 0;
}
1;