#!/usr/bin/perl -w use strict; use lib './'; use Guff; use Data::Dumper; my $data = { type=>'first', value=>0, DESKTOP=> { type=>'second', value=>1, LIBRARY=> { value=>2, type=>'third', REEL=>{ type=>undef }, } }, }; my $g = Guff->new( $data ); print Dumper $g ; #### package Guff; use Carp; use strict; use Guff::Child1; use Data::Dumper; our $child = 'DESKTOP'; our %dispatch = ( first=>'Guff::Child1', ); sub new { my $class = shift; my $in = shift; #my %opt = %{$_[0]} ; my %opt = %{$in}; my $kid = $class . "::child"; no strict 'refs'; do { confess "Missing child attribute $kid ", $$kid unless exists $opt{$$kid}; } if defined ( $opt{$$kid} ); use strict 'refs'; my $self = bless \%opt, $class; $self->init; return $self; } sub init { my $self = shift; my $child = $self->childkey; return unless defined $self->{type}; confess "Invalid child $child -" , Dumper $self unless exists $self->{ $child }; if ( $self->dispatchto ) { $self->{ $child } = $self->dispatchto->new ( $self->{ $child } ) or confess "Failed to dispatch " , Dumper $self; } } sub childkey { my $self = shift; my $kid = ref($self) . "::child"; no strict 'refs'; my $child = $$kid; use strict 'refs'; return $child; } sub dispatchto { my $self = shift; my $key = shift; my $dsp = ref($self) . "::dispatch"; no strict 'refs'; my $dispatch = $$dsp{$self->{type}}; use strict 'refs'; return $dispatch; } 1; #### package Guff::Child1; use Guff; @ISA = qw/Guff/; our %dispatch = ( second=>'Guff::Child2', ); our $child = 'LIBRARY'; 1; package Guff::Child2; use Guff::Child3; @ISA = qw/Guff::Child1/; our %dispatch = ( third=>'Guff::Child3', ); our $child = 'REEL'; 1; package Guff::Child3; use Guff::Child2; @ISA = qw/Guff::Child2/; our %dispatch = ( ); our $child = undef; 1;