Mercurial > pub > Impl
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; |
