comparison _test/temp.pl @ 424:87af445663d7 ref20150831

IMPL::Object::_Base
author cin
date Tue, 03 Apr 2018 10:54:09 +0300
parents 60c2892a577c
children c27434cdd611 eed50c01e758
comparison
equal deleted inserted replaced
423:60c2892a577c 424:87af445663d7
6 use Scalar::Util qw(blessed refaddr); 6 use Scalar::Util qw(blessed refaddr);
7 use YAML::XS qw(Dump Load); 7 use YAML::XS qw(Dump Load);
8 use Data::Dumper; 8 use Data::Dumper;
9 use URI; 9 use URI;
10 10
11 #my $method = _get_ctor("Box", undef, '@_'); 11 package Bar;
12 use base qw(IMPL::Object);
12 13
13 _invoke_ctor("main","x","y","z"); 14 sub CTOR {
14 _invoke_ctor("main","x","y","z");
15
16 sub _invoke_ctor {
17 my ($self) = @_;
18 no strict 'refs';
19 no warnings 'redefine';
20
21 my $method = _get_ctor("Box", undef, '@_');
22
23 *{"${self}::_invoke_ctor"} = $method;
24
25 goto &$method;
26 } 15 }
27 16
28 sub _get_ctor { 17 package Bar2;
29 my ($class, $prev, $t) = @_; 18 use base qw(Bar);
30 no strict 'refs';
31
32 #say "_get_ctor($class, $prev, $t)";
33
34 my $isolate = ((not defined($t)) or ($t ne '@_'));
35
36 my $ctor = $isolate ? *{"${class}::CTOR"}{CODE} : _chain_call(*{"${class}::CTOR"}{CODE}, $prev);
37
38 foreach my $base (@{"${class}::ISA"}) {
39 $ctor = _get_ctor($base, $ctor, exists ${"${class}::ISA"}{$base} ? ${"${class}::ISA"}{$base} : '@_');
40 }
41
42 if ($isolate) {
43 $ctor = _chain_call(_chain_params($ctor, $t), $prev);
44 }
45
46 return $ctor;
47 }
48
49 sub _chain_call {
50 my ($method, $next) = @_;
51
52 return $method unless $next;
53 return $next unless $method;
54
55 return sub { &$method(@_); goto &$next; }
56 }
57
58 sub _chain_params {
59 my ($method, $prepare) = @_;
60
61 return unless $method;
62
63 if (not defined $prepare) {
64 return sub { @_ = (shift); goto &$method };
65 } elsif ($prepare eq '@_') {
66 return $method;
67 } elsif (ref $prepare eq 'CODE') {
68 return sub {
69 @_ = (shift, &$prepare(@_));
70 goto &$method;
71 }
72 }
73 }
74
75 package Obj;
76 19
77 sub CTOR { 20 sub CTOR {
78 say "Obj ", join (',', @_);
79 say Carp::longmess();
80 } 21 }
81 22
82 package Foo; 23 package Foo;
24 use base qw(IMPL::Object::_Base);
83 25
84 BEGIN { 26 sub new {
85 our @ISA = qw(Obj); 27 my $instance = bless {}, shift;
86 our %ISA = ( 28 $instance->__construct();
87 Obj => sub { "hi" } 29 return $instance;
88 );
89 } 30 }
90 31
91 sub CTOR { 32 sub CTOR {
92 say "Foo ", join (',', @_);
93 } 33 }
94 34
95 package Bar; 35 package Foo2;
36 use base qw(Foo);
96 37
97 BEGIN { 38 sub CTOR {
98 our @ISA = qw(Foo); 39
99 our %ISA = ( 40 }
100 Foo => undef 41
101 ); 42 package main;
43
44 my $t = [gettimeofday];
45
46 for(my $i=0; $i <1000000; $i++) {
47 my $v = new Bar2;
102 } 48 }
103 49
104 sub CTOR { 50 say tv_interval($t);
105 say "Bar ", join(',', @_);
106 }
107
108 package Baz;
109
110 sub CTOR {
111 say "Baz ", join(',', @_);
112 }
113
114 package Box;
115
116 BEGIN {
117 our @ISA = qw(Bar Baz);
118 our %ISA = (
119 Bar => sub { shift . "~Box->Bar", @_; },
120 Baz => sub { shift . "~Box->Baz", @_; }
121 );
122 }
123
124 sub CTOR {
125 say "Box ", join(',', @_);
126 }
127 51
128 1; 52 1;