annotate lib/IMPL/Object/_Base.pm @ 423:60c2892a577c ref20150831

working on base class system
author cin
date Mon, 02 Apr 2018 07:35:23 +0300
parents
children 87af445663d7
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;
60c2892a577c working on base class system
cin
parents:
diff changeset
3 use mro;
60c2892a577c working on base class system
cin
parents:
diff changeset
4
60c2892a577c working on base class system
cin
parents:
diff changeset
5 sub _build_ctor {
60c2892a577c working on base class system
cin
parents:
diff changeset
6 my $class = shift;
60c2892a577c working on base class system
cin
parents:
diff changeset
7
60c2892a577c working on base class system
cin
parents:
diff changeset
8 my @isa = reverse @{mro::get_linear_isa($class)};
60c2892a577c working on base class system
cin
parents:
diff changeset
9
60c2892a577c working on base class system
cin
parents:
diff changeset
10
60c2892a577c working on base class system
cin
parents:
diff changeset
11 }
60c2892a577c working on base class system
cin
parents:
diff changeset
12
60c2892a577c working on base class system
cin
parents:
diff changeset
13 sub _get_ctor {
60c2892a577c working on base class system
cin
parents:
diff changeset
14 my ($class, $prev, $t) = @_;
60c2892a577c working on base class system
cin
parents:
diff changeset
15 no strict 'refs';
60c2892a577c working on base class system
cin
parents:
diff changeset
16
60c2892a577c working on base class system
cin
parents:
diff changeset
17 #say "_get_ctor($class, $prev, $t)";
60c2892a577c working on base class system
cin
parents:
diff changeset
18
60c2892a577c working on base class system
cin
parents:
diff changeset
19 my $isolate = ((not defined($t)) or ($t ne '@_'));
60c2892a577c working on base class system
cin
parents:
diff changeset
20
60c2892a577c working on base class system
cin
parents:
diff changeset
21 my $ctor = $isolate ? *{"${class}::CTOR"}{CODE} : _chain_call(*{"${class}::CTOR"}{CODE}, $prev);
60c2892a577c working on base class system
cin
parents:
diff changeset
22
60c2892a577c working on base class system
cin
parents:
diff changeset
23 foreach my $base (@{"${class}::ISA"}) {
60c2892a577c working on base class system
cin
parents:
diff changeset
24 $ctor = _get_ctor($base, $ctor, exists ${"${class}::ISA"}{$base} ? ${"${class}::ISA"}{$base} : '@_');
60c2892a577c working on base class system
cin
parents:
diff changeset
25 }
60c2892a577c working on base class system
cin
parents:
diff changeset
26
60c2892a577c working on base class system
cin
parents:
diff changeset
27 if ($isolate) {
60c2892a577c working on base class system
cin
parents:
diff changeset
28 $ctor = _chain_call(_chain_params($ctor, $t), $prev);
60c2892a577c working on base class system
cin
parents:
diff changeset
29 }
60c2892a577c working on base class system
cin
parents:
diff changeset
30
60c2892a577c working on base class system
cin
parents:
diff changeset
31 return $ctor;
60c2892a577c working on base class system
cin
parents:
diff changeset
32 }
60c2892a577c working on base class system
cin
parents:
diff changeset
33
60c2892a577c working on base class system
cin
parents:
diff changeset
34 sub _chain_call {
60c2892a577c working on base class system
cin
parents:
diff changeset
35 my ($method, $next) = @_;
60c2892a577c working on base class system
cin
parents:
diff changeset
36
60c2892a577c working on base class system
cin
parents:
diff changeset
37 return $method unless $next;
60c2892a577c working on base class system
cin
parents:
diff changeset
38 return $next unless $method;
60c2892a577c working on base class system
cin
parents:
diff changeset
39
60c2892a577c working on base class system
cin
parents:
diff changeset
40 return sub { &$method(@_); goto &$next; }
60c2892a577c working on base class system
cin
parents:
diff changeset
41 }
60c2892a577c working on base class system
cin
parents:
diff changeset
42
60c2892a577c working on base class system
cin
parents:
diff changeset
43 sub _chain_params {
60c2892a577c working on base class system
cin
parents:
diff changeset
44 my ($method, $prepare) = @_;
60c2892a577c working on base class system
cin
parents:
diff changeset
45
60c2892a577c working on base class system
cin
parents:
diff changeset
46 return unless $method;
60c2892a577c working on base class system
cin
parents:
diff changeset
47
60c2892a577c working on base class system
cin
parents:
diff changeset
48 if (not defined $prepare) {
60c2892a577c working on base class system
cin
parents:
diff changeset
49 return sub { @_ = (shift); goto &$method };
60c2892a577c working on base class system
cin
parents:
diff changeset
50 } elsif ($prepare eq '@_') {
60c2892a577c working on base class system
cin
parents:
diff changeset
51 return $method;
60c2892a577c working on base class system
cin
parents:
diff changeset
52 } elsif (ref $prepare eq 'CODE') {
60c2892a577c working on base class system
cin
parents:
diff changeset
53 return sub {
60c2892a577c working on base class system
cin
parents:
diff changeset
54 @_ = (shift, &$prepare(@_));
60c2892a577c working on base class system
cin
parents:
diff changeset
55 goto &$method;
60c2892a577c working on base class system
cin
parents:
diff changeset
56 }
60c2892a577c working on base class system
cin
parents:
diff changeset
57 }
60c2892a577c working on base class system
cin
parents:
diff changeset
58 }
60c2892a577c working on base class system
cin
parents:
diff changeset
59
60c2892a577c working on base class system
cin
parents:
diff changeset
60 1;