annotate lib/IMPL/Object/_Base.pm @ 424:87af445663d7 ref20150831

IMPL::Object::_Base
author cin
date Tue, 03 Apr 2018 10:54:09 +0300
parents 60c2892a577c
children c27434cdd611
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
423
60c2892a577c working on base class system
cin
parents:
diff changeset
1 package IMPL::Object::_Base;
60c2892a577c working on base class system
cin
parents:
diff changeset
2 use strict;
424
87af445663d7 IMPL::Object::_Base
cin
parents: 423
diff changeset
3 use warnings;
423
60c2892a577c working on base class system
cin
parents:
diff changeset
4 use mro;
60c2892a577c working on base class system
cin
parents:
diff changeset
5
424
87af445663d7 IMPL::Object::_Base
cin
parents: 423
diff changeset
6 sub __construct;
87af445663d7 IMPL::Object::_Base
cin
parents: 423
diff changeset
7 sub __destroy;
87af445663d7 IMPL::Object::_Base
cin
parents: 423
diff changeset
8
87af445663d7 IMPL::Object::_Base
cin
parents: 423
diff changeset
9 *__construct = _strap_ctor(__PACKAGE__);
87af445663d7 IMPL::Object::_Base
cin
parents: 423
diff changeset
10 *__destroy = _strap_dtor(__PACKAGE__);
87af445663d7 IMPL::Object::_Base
cin
parents: 423
diff changeset
11
87af445663d7 IMPL::Object::_Base
cin
parents: 423
diff changeset
12 sub DESTROY {
87af445663d7 IMPL::Object::_Base
cin
parents: 423
diff changeset
13 shift->__destroy();
87af445663d7 IMPL::Object::_Base
cin
parents: 423
diff changeset
14 }
87af445663d7 IMPL::Object::_Base
cin
parents: 423
diff changeset
15
87af445663d7 IMPL::Object::_Base
cin
parents: 423
diff changeset
16 sub _strap_ctor {
87af445663d7 IMPL::Object::_Base
cin
parents: 423
diff changeset
17 my ($class, $ctor) = @_;
87af445663d7 IMPL::Object::_Base
cin
parents: 423
diff changeset
18 no strict 'refs';
87af445663d7 IMPL::Object::_Base
cin
parents: 423
diff changeset
19 no warnings 'redefine';
423
60c2892a577c working on base class system
cin
parents:
diff changeset
20
424
87af445663d7 IMPL::Object::_Base
cin
parents: 423
diff changeset
21 return sub {
87af445663d7 IMPL::Object::_Base
cin
parents: 423
diff changeset
22 my $self = ref shift;
87af445663d7 IMPL::Object::_Base
cin
parents: 423
diff changeset
23
87af445663d7 IMPL::Object::_Base
cin
parents: 423
diff changeset
24 if ($self ne $class) {
87af445663d7 IMPL::Object::_Base
cin
parents: 423
diff changeset
25 my $t = _get_ctor($self, undef, '@_');
87af445663d7 IMPL::Object::_Base
cin
parents: 423
diff changeset
26 *{"${self}::__construct"} = _strap_ctor($self, $t);
87af445663d7 IMPL::Object::_Base
cin
parents: 423
diff changeset
27 goto &$t if $t;
87af445663d7 IMPL::Object::_Base
cin
parents: 423
diff changeset
28 } else {
87af445663d7 IMPL::Object::_Base
cin
parents: 423
diff changeset
29 goto &$ctor if $ctor;
87af445663d7 IMPL::Object::_Base
cin
parents: 423
diff changeset
30 }
87af445663d7 IMPL::Object::_Base
cin
parents: 423
diff changeset
31 };
87af445663d7 IMPL::Object::_Base
cin
parents: 423
diff changeset
32 }
87af445663d7 IMPL::Object::_Base
cin
parents: 423
diff changeset
33
87af445663d7 IMPL::Object::_Base
cin
parents: 423
diff changeset
34 sub _strap_dtor {
87af445663d7 IMPL::Object::_Base
cin
parents: 423
diff changeset
35 my ($class, $dtor) = @_;
423
60c2892a577c working on base class system
cin
parents:
diff changeset
36
424
87af445663d7 IMPL::Object::_Base
cin
parents: 423
diff changeset
37 no strict 'refs';
87af445663d7 IMPL::Object::_Base
cin
parents: 423
diff changeset
38 no warnings 'redefine';
423
60c2892a577c working on base class system
cin
parents:
diff changeset
39
424
87af445663d7 IMPL::Object::_Base
cin
parents: 423
diff changeset
40 return sub {
87af445663d7 IMPL::Object::_Base
cin
parents: 423
diff changeset
41 my $self = ref shift;
87af445663d7 IMPL::Object::_Base
cin
parents: 423
diff changeset
42
87af445663d7 IMPL::Object::_Base
cin
parents: 423
diff changeset
43 if ($self ne $class) {
87af445663d7 IMPL::Object::_Base
cin
parents: 423
diff changeset
44 my $t = _get_dtor($self);
87af445663d7 IMPL::Object::_Base
cin
parents: 423
diff changeset
45 *{"${self}::__destroy"} = _strap_dtor($self, $t);
87af445663d7 IMPL::Object::_Base
cin
parents: 423
diff changeset
46 goto &$t if $t;
87af445663d7 IMPL::Object::_Base
cin
parents: 423
diff changeset
47 } else {
87af445663d7 IMPL::Object::_Base
cin
parents: 423
diff changeset
48 goto &$dtor if $dtor;
87af445663d7 IMPL::Object::_Base
cin
parents: 423
diff changeset
49 }
87af445663d7 IMPL::Object::_Base
cin
parents: 423
diff changeset
50 };
423
60c2892a577c working on base class system
cin
parents:
diff changeset
51 }
60c2892a577c working on base class system
cin
parents:
diff changeset
52
60c2892a577c working on base class system
cin
parents:
diff changeset
53 sub _get_ctor {
60c2892a577c working on base class system
cin
parents:
diff changeset
54 my ($class, $prev, $t) = @_;
60c2892a577c working on base class system
cin
parents:
diff changeset
55 no strict 'refs';
60c2892a577c working on base class system
cin
parents:
diff changeset
56
60c2892a577c working on base class system
cin
parents:
diff changeset
57 #say "_get_ctor($class, $prev, $t)";
60c2892a577c working on base class system
cin
parents:
diff changeset
58
60c2892a577c working on base class system
cin
parents:
diff changeset
59 my $isolate = ((not defined($t)) or ($t ne '@_'));
60c2892a577c working on base class system
cin
parents:
diff changeset
60
60c2892a577c working on base class system
cin
parents:
diff changeset
61 my $ctor = $isolate ? *{"${class}::CTOR"}{CODE} : _chain_call(*{"${class}::CTOR"}{CODE}, $prev);
60c2892a577c working on base class system
cin
parents:
diff changeset
62
60c2892a577c working on base class system
cin
parents:
diff changeset
63 foreach my $base (@{"${class}::ISA"}) {
60c2892a577c working on base class system
cin
parents:
diff changeset
64 $ctor = _get_ctor($base, $ctor, exists ${"${class}::ISA"}{$base} ? ${"${class}::ISA"}{$base} : '@_');
60c2892a577c working on base class system
cin
parents:
diff changeset
65 }
60c2892a577c working on base class system
cin
parents:
diff changeset
66
60c2892a577c working on base class system
cin
parents:
diff changeset
67 if ($isolate) {
60c2892a577c working on base class system
cin
parents:
diff changeset
68 $ctor = _chain_call(_chain_params($ctor, $t), $prev);
60c2892a577c working on base class system
cin
parents:
diff changeset
69 }
60c2892a577c working on base class system
cin
parents:
diff changeset
70
60c2892a577c working on base class system
cin
parents:
diff changeset
71 return $ctor;
60c2892a577c working on base class system
cin
parents:
diff changeset
72 }
60c2892a577c working on base class system
cin
parents:
diff changeset
73
424
87af445663d7 IMPL::Object::_Base
cin
parents: 423
diff changeset
74 sub _get_dtor {
87af445663d7 IMPL::Object::_Base
cin
parents: 423
diff changeset
75 my ($class, $prev) = @_;
87af445663d7 IMPL::Object::_Base
cin
parents: 423
diff changeset
76 no strict 'refs';
87af445663d7 IMPL::Object::_Base
cin
parents: 423
diff changeset
77
87af445663d7 IMPL::Object::_Base
cin
parents: 423
diff changeset
78 my $dtor = _chain_call(*{"${class}::DTOR"}{CODE}, $prev);
87af445663d7 IMPL::Object::_Base
cin
parents: 423
diff changeset
79 $dtor = _get_dtor($_, $dtor) foreach @{"${class}::ISA"};
87af445663d7 IMPL::Object::_Base
cin
parents: 423
diff changeset
80
87af445663d7 IMPL::Object::_Base
cin
parents: 423
diff changeset
81 return $dtor;
87af445663d7 IMPL::Object::_Base
cin
parents: 423
diff changeset
82 }
87af445663d7 IMPL::Object::_Base
cin
parents: 423
diff changeset
83
423
60c2892a577c working on base class system
cin
parents:
diff changeset
84 sub _chain_call {
60c2892a577c working on base class system
cin
parents:
diff changeset
85 my ($method, $next) = @_;
60c2892a577c working on base class system
cin
parents:
diff changeset
86
60c2892a577c working on base class system
cin
parents:
diff changeset
87 return $method unless $next;
60c2892a577c working on base class system
cin
parents:
diff changeset
88 return $next unless $method;
60c2892a577c working on base class system
cin
parents:
diff changeset
89
60c2892a577c working on base class system
cin
parents:
diff changeset
90 return sub { &$method(@_); goto &$next; }
60c2892a577c working on base class system
cin
parents:
diff changeset
91 }
60c2892a577c working on base class system
cin
parents:
diff changeset
92
60c2892a577c working on base class system
cin
parents:
diff changeset
93 sub _chain_params {
60c2892a577c working on base class system
cin
parents:
diff changeset
94 my ($method, $prepare) = @_;
60c2892a577c working on base class system
cin
parents:
diff changeset
95
60c2892a577c working on base class system
cin
parents:
diff changeset
96 return unless $method;
60c2892a577c working on base class system
cin
parents:
diff changeset
97
60c2892a577c working on base class system
cin
parents:
diff changeset
98 if (not defined $prepare) {
60c2892a577c working on base class system
cin
parents:
diff changeset
99 return sub { @_ = (shift); goto &$method };
60c2892a577c working on base class system
cin
parents:
diff changeset
100 } elsif ($prepare eq '@_') {
60c2892a577c working on base class system
cin
parents:
diff changeset
101 return $method;
60c2892a577c working on base class system
cin
parents:
diff changeset
102 } elsif (ref $prepare eq 'CODE') {
60c2892a577c working on base class system
cin
parents:
diff changeset
103 return sub {
60c2892a577c working on base class system
cin
parents:
diff changeset
104 @_ = (shift, &$prepare(@_));
60c2892a577c working on base class system
cin
parents:
diff changeset
105 goto &$method;
60c2892a577c working on base class system
cin
parents:
diff changeset
106 }
60c2892a577c working on base class system
cin
parents:
diff changeset
107 }
60c2892a577c working on base class system
cin
parents:
diff changeset
108 }
60c2892a577c working on base class system
cin
parents:
diff changeset
109
60c2892a577c working on base class system
cin
parents:
diff changeset
110 1;