Mercurial > pub > Impl
view _test/temp.pl @ 423:60c2892a577c ref20150831
working on base class system
author | cin |
---|---|
date | Mon, 02 Apr 2018 07:35:23 +0300 |
parents | b0481c071bea |
children | 87af445663d7 |
line wrap: on
line source
#!/usr/bin/perl use strict; use v5.10; use Carp; use Time::HiRes qw(gettimeofday tv_interval); use Scalar::Util qw(blessed refaddr); use YAML::XS qw(Dump Load); use Data::Dumper; use URI; #my $method = _get_ctor("Box", undef, '@_'); _invoke_ctor("main","x","y","z"); _invoke_ctor("main","x","y","z"); sub _invoke_ctor { my ($self) = @_; no strict 'refs'; no warnings 'redefine'; my $method = _get_ctor("Box", undef, '@_'); *{"${self}::_invoke_ctor"} = $method; goto &$method; } sub _get_ctor { my ($class, $prev, $t) = @_; no strict 'refs'; #say "_get_ctor($class, $prev, $t)"; my $isolate = ((not defined($t)) or ($t ne '@_')); my $ctor = $isolate ? *{"${class}::CTOR"}{CODE} : _chain_call(*{"${class}::CTOR"}{CODE}, $prev); foreach my $base (@{"${class}::ISA"}) { $ctor = _get_ctor($base, $ctor, exists ${"${class}::ISA"}{$base} ? ${"${class}::ISA"}{$base} : '@_'); } if ($isolate) { $ctor = _chain_call(_chain_params($ctor, $t), $prev); } return $ctor; } sub _chain_call { my ($method, $next) = @_; return $method unless $next; return $next unless $method; return sub { &$method(@_); goto &$next; } } sub _chain_params { my ($method, $prepare) = @_; return unless $method; if (not defined $prepare) { return sub { @_ = (shift); goto &$method }; } elsif ($prepare eq '@_') { return $method; } elsif (ref $prepare eq 'CODE') { return sub { @_ = (shift, &$prepare(@_)); goto &$method; } } } package Obj; sub CTOR { say "Obj ", join (',', @_); say Carp::longmess(); } package Foo; BEGIN { our @ISA = qw(Obj); our %ISA = ( Obj => sub { "hi" } ); } sub CTOR { say "Foo ", join (',', @_); } package Bar; BEGIN { our @ISA = qw(Foo); our %ISA = ( Foo => undef ); } sub CTOR { say "Bar ", join(',', @_); } package Baz; sub CTOR { say "Baz ", join(',', @_); } package Box; BEGIN { our @ISA = qw(Bar Baz); our %ISA = ( Bar => sub { shift . "~Box->Bar", @_; }, Baz => sub { shift . "~Box->Baz", @_; } ); } sub CTOR { say "Box ", join(',', @_); } 1;