| 1 | 1 package IMPL::Object::Abstract; | 
|  | 2 use strict; | 
|  | 3 use warnings; | 
|  | 4 | 
|  | 5 use base qw(IMPL::Class::Meta); | 
|  | 6 | 
|  | 7 our $MemoryLeakProtection; | 
|  | 8 my $Cleanup = 0; | 
|  | 9 | 
|  | 10 my %cacheCTOR; | 
|  | 11 | 
|  | 12 my $t = 0; | 
|  | 13 sub cache_ctor { | 
|  | 14     my $class = shift; | 
|  | 15 | 
|  | 16     no strict 'refs'; | 
|  | 17     my @sequence; | 
|  | 18 | 
|  | 19     my $refCTORS = *{"${class}::CTOR"}{HASH}; | 
|  | 20 | 
|  | 21     foreach my $super ( @{"${class}::ISA"} ) { | 
|  | 22 	my $superSequence = $cacheCTOR{$super} || cache_ctor($super); | 
|  | 23 | 
|  | 24 	my $mapper = $refCTORS ? $refCTORS->{$super} : undef; | 
|  | 25 	if (ref $mapper eq 'CODE') { | 
|  | 26 	    if ($mapper == *_pass_throgh_mapper{CODE}) { | 
|  | 27 		push @sequence,@$superSequence; | 
|  | 28 	    } else { | 
|  | 29 		push @sequence, sub { | 
|  | 30 		    my $this = shift; | 
|  | 31 		    $this->$_($mapper->(@_)) foreach @$superSequence; | 
|  | 32 		}; | 
|  | 33 	    } | 
|  | 34 	} else { | 
|  | 35 	    warn "Unsupported mapper type, in '$class' for the super class '$super'" if $mapper; | 
|  | 36 	    push @sequence, sub { | 
|  | 37 		my $this = shift; | 
|  | 38 		$this->$_() foreach @$superSequence; | 
|  | 39 	    }; | 
|  | 40 	} | 
|  | 41     } | 
|  | 42 | 
|  | 43     push @sequence, *{"${class}::CTOR"}{CODE} if *{"${class}::CTOR"}{CODE}; | 
|  | 44 | 
|  | 45     $cacheCTOR{$class} = \@sequence; | 
|  | 46     return \@sequence; | 
|  | 47 } | 
|  | 48 | 
|  | 49 sub callCTOR { | 
|  | 50     my $self = shift; | 
|  | 51     my $class = ref $self; | 
|  | 52 | 
|  | 53     $self->$_(@_) foreach @{$cacheCTOR{$class} || cache_ctor($class)}; | 
|  | 54 } | 
|  | 55 | 
|  | 56 sub superCTOR { | 
|  | 57     my $this = shift; | 
|  | 58 | 
|  | 59     warn "The mehod is deprecated, at " . caller; | 
|  | 60 } | 
|  | 61 | 
|  | 62 sub toString { | 
|  | 63     my $self = shift; | 
|  | 64 | 
|  | 65     return (ref $self || $self); | 
|  | 66 } | 
|  | 67 | 
| 33 | 68 sub isDisposed { | 
|  | 69     0; | 
| 1 | 70 } | 
|  | 71 | 
| 33 | 72 #sub DESTROY { | 
|  | 73 #    if ($MemoryLeakProtection and $Cleanup) { | 
|  | 74 #        my $this = shift; | 
|  | 75 #        warn sprintf("Object leaks: %s of type %s %s",$this->can('ToString') ? $this->ToString : $this,ref $this,UNIVERSAL::can($this,'_dump') ? $this->_dump : ''); | 
|  | 76 #    } | 
|  | 77 #} | 
|  | 78 | 
| 1 | 79 sub END { | 
|  | 80     $Cleanup = 1; | 
|  | 81 } | 
|  | 82 | 
|  | 83 sub _pass_throgh_mapper { | 
|  | 84     @_; | 
|  | 85 } | 
|  | 86 | 
| 24 | 87 sub PassArgs { | 
|  | 88     \&_pass_throgh_mapper; | 
|  | 89 } | 
|  | 90 | 
| 1 | 91 sub PassThroughArgs { | 
|  | 92     my $class = shift; | 
|  | 93     $class = ref $class || $class; | 
|  | 94     no strict 'refs'; | 
|  | 95     no warnings 'once'; | 
|  | 96     ${"${class}::CTOR"}{$_} = \&_pass_throgh_mapper foreach @{"${class}::ISA"}; | 
|  | 97 } | 
|  | 98 | 
|  | 99 package self; | 
|  | 100 | 
|  | 101 our $AUTOLOAD; | 
|  | 102 sub AUTOLOAD { | 
|  | 103     goto &{caller(). substr $AUTOLOAD,4}; | 
|  | 104 } | 
|  | 105 | 
|  | 106 package supercall; | 
|  | 107 | 
|  | 108 our $AUTOLOAD; | 
|  | 109 sub AUTOLOAD { | 
|  | 110     my $sub; | 
|  | 111     my $methodName = substr $AUTOLOAD,11; | 
|  | 112     no strict 'refs'; | 
|  | 113     $sub = $_->can($methodName) and $sub->(@_) foreach @{caller().'::ISA'}; | 
|  | 114 } | 
|  | 115 | 
|  | 116 =pod | 
|  | 117 =h1 SYNOPSIS | 
|  | 118 | 
|  | 119 package MyBaseObject; | 
|  | 120 use base qw(IMPL::Object::Abstract); | 
|  | 121 | 
|  | 122 sub new { | 
|  | 123     # own implementation of the new opeator | 
|  | 124 } | 
|  | 125 | 
|  | 126 sub surrogate { | 
|  | 127     # own implementation of the surrogate operator | 
|  | 128 } | 
|  | 129 | 
|  | 130 =h1 DESCRIPTION | 
|  | 131 | 
|  | 132        , | 
|  | 133  . | 
| 2 | 134 =cut | 
| 1 | 135 | 
|  | 136 1; |