# Copyright (c) 2001-2011 bivio Software, Inc. All rights reserved. # # Visit http://www.bivio.biz for more info. # # This library is free software; you can redistribute it and/or modify # it under the terms of the GNU Lesser General Public License as # published by the Free Software Foundation; either version 2.1 of the # License, or (at your option) any later version. # # This library is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public # License along with this library; If not, you may get a copy from: # http://www.opensource.org/licenses/lgpl-license.html # # $Id: Delegator.pm,v 2.6 2011/02/18 17:55:41 nagler Exp $ package Bivio::Delegator; use strict; use Bivio::Base 'Bivio.UNIVERSAL'; # C delegates implementation to another class. Subclasses # must have an entry in ClassLoader.delegates. our($VERSION) = sprintf('%d.%02d', q$Revision: 2.6 $ =~ /\d+/g); our($AUTOLOAD); my($_CL) = b_use('IO.ClassLoader'); my($_IDI) = __PACKAGE__->instance_data_index; my($_MAP) = {}; our($last) = ''; sub AUTOLOAD { my($proto) = shift; my($method) = $AUTOLOAD =~ /([^:]+)$/; return if $method eq 'DESTROY'; die($AUTOLOAD) if $AUTOLOAD eq $last; local($last) = $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;