Mercurial > pub > Impl
diff Lib/IMPL/Object.pm @ 0:03e58a454b20
Создан репозитарий
author | Sergey |
---|---|
date | Tue, 14 Jul 2009 12:54:37 +0400 |
parents | |
children | 78cd38551534 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Lib/IMPL/Object.pm Tue Jul 14 12:54:37 2009 +0400 @@ -0,0 +1,187 @@ +package IMPL::Object; +use strict; + +use base qw(IMPL::Class::Meta); + +our $MemoryLeakProtection; +my $Cleanup = 0; +our $Debug; +our %leaked_objects; + +my %cacheCTOR; + + +sub new { + my $class = shift; + my $self = bless {}, ref($class) || $class; + + $self->$_(@_) foreach @{$cacheCTOR{ref $self} || cache_ctor(ref $self)}; + + $self; +} +my $t = 0; +sub cache_ctor { + my $class = shift; + + no strict 'refs'; + my @sequence; + + my $refCTORS = *{"${class}::CTOR"}{HASH}; + + foreach my $super ( @{"${class}::ISA"} ) { + my $superSequence = $cacheCTOR{$super} || cache_ctor($super); + + my $mapper = $refCTORS ? $refCTORS->{$super} : undef; + if (ref $mapper eq 'CODE') { + if ($mapper == *_pass_throgh_mapper{CODE}) { + push @sequence,@$superSequence; + } else { + push @sequence, sub { + my $this = shift; + $this->$_($mapper->(@_)) foreach @$superSequence; + }; + } + } else { + warn "Unsupported mapper type, in '$class' for the super class '$super'" if $mapper; + push @sequence, sub { + my $this = shift; + $this->$_() foreach @$superSequence; + }; + } + } + + push @sequence, *{"${class}::CTOR"}{CODE} if *{"${class}::CTOR"}{CODE}; + + $cacheCTOR{$class} = \@sequence; + return \@sequence; +} + +sub callCTOR { + my $self = shift; + my $class = ref $self; + + $self->$_(@_) foreach @{$cacheCTOR{$class} || cache_ctor($class)}; +} + +sub surrogate { + bless {}, ref $_[0] || $_[0]; +} + +sub superCTOR { + my $this = shift; + + warn "The mehod is deprecated, at " . caller; +} + +sub toString { + my $self = shift; + + return (ref $self || $self); +} + +sub DESTROY { + if ($MemoryLeakProtection and $Cleanup) { + my $this = shift; + warn sprintf("Object leaks: %s of type %s %s",$this->can('ToString') ? $this->ToString : $this,ref $this,UNIVERSAL::can($this,'_dump') ? $this->_dump : ''); + } +} + +sub END { + $Cleanup = 1; + $MemoryLeakProtection = 0 unless $Debug; +} + +sub _pass_throgh_mapper { + @_; +} + +sub PassThroughArgs { + my $class = shift; + $class = ref $class || $class; + no strict 'refs'; + no warnings 'once'; + ${"${class}::CTOR"}{$_} = \&_pass_throgh_mapper foreach @{"${class}::ISA"}; +} + +package self; + +our $AUTOLOAD; +sub AUTOLOAD { + goto &{caller(). substr $AUTOLOAD,4}; +} + +package supercall; + +our $AUTOLOAD; +sub AUTOLOAD { + my $sub; + my $methodName = substr $AUTOLOAD,11; + no strict 'refs'; + $sub = $_->can($methodName) and $sub->(@_) foreach @{caller().'::ISA'}; +} + +=pod +=h1 SYNOPSIS + +package Foo; +use base qw(IMPL::Object); + +sub CTOR { + my ($this,$arg) = @_; + print "Foo: $arg\n"; +} + +package Bar; +use base qw(IMPL::Object); + +sub CTOR { + my ($this,$arg) = @_; + print "Bar: $arg\n"; +} + +package Baz; +use base qw(Foo Bar); + +our %CTOR = ( + Foo => sub { my %args = @_; $args{Mazzi}; }, + Bar => sub { my %args = @_; $args{Fugi}; } +); + +package Composite; +use base qw(Baz Foo Bar); + +our %CTOR = ( + Foo => undef, + Bar => undef +); + +sub CTOR { + my ($this,%args) = @_; + + print "Composite: $args{Text}\n"; +} + +package main; + +my $obj = new Composite( + Text => 'Hello World!', + Mazzi => 'Mazzi', + Fugi => 'Fugi' +); + +# will print +# +# Foo: Mazzi +# Bar: Fugi +# Foo: +# Bar: +# Composite: Hello World! + +=h1 Description +Áàçîâûé êëàññ äëÿ îáúåêòîâ. Ðåàëèçóåò ìíîæåñòâåííîå íàñëåäîâàíèå + + +=h1 Members +=cut + +1; \ No newline at end of file