annotate lib/IMPL/Object/_Base.pm @ 427:09e0086a82a7 ref20150831 tip

Merge
author cin
date Tue, 15 May 2018 00:51:33 +0300
parents c27434cdd611
children
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__);
425
cin
parents: 424
diff changeset
10 *__destroy = _strap_dtor(__PACKAGE__);
424
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 {
425
cin
parents: 424
diff changeset
17 my ( $class, $ctor ) = @_;
424
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';
425
cin
parents: 424
diff changeset
20
cin
parents: 424
diff changeset
21 return $ctor
cin
parents: 424
diff changeset
22 ? sub {
cin
parents: 424
diff changeset
23 my $self = ref $_[0];
424
87af445663d7 IMPL::Object::_Base
cin
parents: 423
diff changeset
24
425
cin
parents: 424
diff changeset
25 if ( $self ne $class ) {
cin
parents: 424
diff changeset
26 my $t = _get_ctor( $self, undef, '@_' );
cin
parents: 424
diff changeset
27 *{"${self}::__construct"} = _strap_ctor( $self, $t );
cin
parents: 424
diff changeset
28 goto &$t;
cin
parents: 424
diff changeset
29 }
cin
parents: 424
diff changeset
30
cin
parents: 424
diff changeset
31 goto &$ctor;
cin
parents: 424
diff changeset
32 }
cin
parents: 424
diff changeset
33 : sub {
cin
parents: 424
diff changeset
34 my $self = ref $_[0];
cin
parents: 424
diff changeset
35 if ( $self ne $class ) {
cin
parents: 424
diff changeset
36 my $t = _get_ctor( $self, undef, '@_' );
cin
parents: 424
diff changeset
37 *{"${self}::__construct"} = _strap_ctor( $self, $t );
424
87af445663d7 IMPL::Object::_Base
cin
parents: 423
diff changeset
38 goto &$t if $t;
87af445663d7 IMPL::Object::_Base
cin
parents: 423
diff changeset
39 }
425
cin
parents: 424
diff changeset
40 };
424
87af445663d7 IMPL::Object::_Base
cin
parents: 423
diff changeset
41 }
87af445663d7 IMPL::Object::_Base
cin
parents: 423
diff changeset
42
87af445663d7 IMPL::Object::_Base
cin
parents: 423
diff changeset
43 sub _strap_dtor {
425
cin
parents: 424
diff changeset
44 my ( $class, $dtor ) = @_;
424
87af445663d7 IMPL::Object::_Base
cin
parents: 423
diff changeset
45 no strict 'refs';
87af445663d7 IMPL::Object::_Base
cin
parents: 423
diff changeset
46 no warnings 'redefine';
425
cin
parents: 424
diff changeset
47
cin
parents: 424
diff changeset
48 return $dtor
cin
parents: 424
diff changeset
49 ? sub {
cin
parents: 424
diff changeset
50 my $self = ref $_[0];
424
87af445663d7 IMPL::Object::_Base
cin
parents: 423
diff changeset
51
425
cin
parents: 424
diff changeset
52 if ( $self ne $class ) {
424
87af445663d7 IMPL::Object::_Base
cin
parents: 423
diff changeset
53 my $t = _get_dtor($self);
425
cin
parents: 424
diff changeset
54 *{"${self}::__destroy"} = _strap_dtor( $self, $t );
cin
parents: 424
diff changeset
55 goto &$t;
424
87af445663d7 IMPL::Object::_Base
cin
parents: 423
diff changeset
56 }
425
cin
parents: 424
diff changeset
57
cin
parents: 424
diff changeset
58 goto &$dtor;
cin
parents: 424
diff changeset
59 }
cin
parents: 424
diff changeset
60 : sub {
cin
parents: 424
diff changeset
61 my $self = ref $_[0];
cin
parents: 424
diff changeset
62 if ( $self ne $class ) {
cin
parents: 424
diff changeset
63 my $t = _get_dtor($self);
cin
parents: 424
diff changeset
64 *{"${self}::__destroy"} = _strap_dtor( $self, $t );
cin
parents: 424
diff changeset
65 goto &$t if $t;
cin
parents: 424
diff changeset
66 }
cin
parents: 424
diff changeset
67 };
423
60c2892a577c working on base class system
cin
parents:
diff changeset
68 }
60c2892a577c working on base class system
cin
parents:
diff changeset
69
60c2892a577c working on base class system
cin
parents:
diff changeset
70 sub _get_ctor {
425
cin
parents: 424
diff changeset
71 my ( $class, $prev, $t ) = @_;
423
60c2892a577c working on base class system
cin
parents:
diff changeset
72 no strict 'refs';
425
cin
parents: 424
diff changeset
73
423
60c2892a577c working on base class system
cin
parents:
diff changeset
74 #say "_get_ctor($class, $prev, $t)";
425
cin
parents: 424
diff changeset
75
cin
parents: 424
diff changeset
76 my $isolate = ( ( not defined($t) ) or ( $t ne '@_' ) );
cin
parents: 424
diff changeset
77
cin
parents: 424
diff changeset
78 my $ctor =
cin
parents: 424
diff changeset
79 $isolate
cin
parents: 424
diff changeset
80 ? *{"${class}::CTOR"}{CODE}
cin
parents: 424
diff changeset
81 : _chain_call( *{"${class}::CTOR"}{CODE}, $prev );
cin
parents: 424
diff changeset
82
cin
parents: 424
diff changeset
83 foreach my $base ( @{"${class}::ISA"} ) {
cin
parents: 424
diff changeset
84 $ctor = _get_ctor( $base, $ctor,
cin
parents: 424
diff changeset
85 exists ${"${class}::ISA"}{$base}
cin
parents: 424
diff changeset
86 ? ${"${class}::ISA"}{$base}
cin
parents: 424
diff changeset
87 : '@_' );
423
60c2892a577c working on base class system
cin
parents:
diff changeset
88 }
425
cin
parents: 424
diff changeset
89
423
60c2892a577c working on base class system
cin
parents:
diff changeset
90 if ($isolate) {
425
cin
parents: 424
diff changeset
91 $ctor = _chain_call( _chain_params( $ctor, $t ), $prev );
423
60c2892a577c working on base class system
cin
parents:
diff changeset
92 }
425
cin
parents: 424
diff changeset
93
423
60c2892a577c working on base class system
cin
parents:
diff changeset
94 return $ctor;
60c2892a577c working on base class system
cin
parents:
diff changeset
95 }
60c2892a577c working on base class system
cin
parents:
diff changeset
96
424
87af445663d7 IMPL::Object::_Base
cin
parents: 423
diff changeset
97 sub _get_dtor {
425
cin
parents: 424
diff changeset
98 my ( $class, $prev ) = @_;
424
87af445663d7 IMPL::Object::_Base
cin
parents: 423
diff changeset
99 no strict 'refs';
425
cin
parents: 424
diff changeset
100
cin
parents: 424
diff changeset
101 my $dtor = _chain_call( *{"${class}::DTOR"}{CODE}, $prev );
cin
parents: 424
diff changeset
102 $dtor = _get_dtor( $_, $dtor ) foreach @{"${class}::ISA"};
cin
parents: 424
diff changeset
103
424
87af445663d7 IMPL::Object::_Base
cin
parents: 423
diff changeset
104 return $dtor;
87af445663d7 IMPL::Object::_Base
cin
parents: 423
diff changeset
105 }
87af445663d7 IMPL::Object::_Base
cin
parents: 423
diff changeset
106
423
60c2892a577c working on base class system
cin
parents:
diff changeset
107 sub _chain_call {
425
cin
parents: 424
diff changeset
108 my ( $method, $next ) = @_;
cin
parents: 424
diff changeset
109
423
60c2892a577c working on base class system
cin
parents:
diff changeset
110 return $method unless $next;
425
cin
parents: 424
diff changeset
111 return $next unless $method;
cin
parents: 424
diff changeset
112
423
60c2892a577c working on base class system
cin
parents:
diff changeset
113 return sub { &$method(@_); goto &$next; }
60c2892a577c working on base class system
cin
parents:
diff changeset
114 }
60c2892a577c working on base class system
cin
parents:
diff changeset
115
60c2892a577c working on base class system
cin
parents:
diff changeset
116 sub _chain_params {
425
cin
parents: 424
diff changeset
117 my ( $method, $prepare ) = @_;
cin
parents: 424
diff changeset
118
423
60c2892a577c working on base class system
cin
parents:
diff changeset
119 return unless $method;
425
cin
parents: 424
diff changeset
120
cin
parents: 424
diff changeset
121 if ( not defined $prepare ) {
423
60c2892a577c working on base class system
cin
parents:
diff changeset
122 return sub { @_ = (shift); goto &$method };
425
cin
parents: 424
diff changeset
123 }
cin
parents: 424
diff changeset
124 elsif ( $prepare eq '@_' ) {
423
60c2892a577c working on base class system
cin
parents:
diff changeset
125 return $method;
425
cin
parents: 424
diff changeset
126 }
cin
parents: 424
diff changeset
127 elsif ( ref $prepare eq 'CODE' ) {
423
60c2892a577c working on base class system
cin
parents:
diff changeset
128 return sub {
425
cin
parents: 424
diff changeset
129 @_ = ( shift, &$prepare(@_) );
423
60c2892a577c working on base class system
cin
parents:
diff changeset
130 goto &$method;
425
cin
parents: 424
diff changeset
131 }
423
60c2892a577c working on base class system
cin
parents:
diff changeset
132 }
60c2892a577c working on base class system
cin
parents:
diff changeset
133 }
60c2892a577c working on base class system
cin
parents:
diff changeset
134
425
cin
parents: 424
diff changeset
135 1;