G'day Amblikai,
"Is that something thats natively possible?"
Yes. The code below requires a minimum Perl version of 5.10.0
(for the mro pragma).
Update (correction):
It actually needs a minimum version of 5.10.1 for the parent pragma;
mro still needs a minimum of 5.10.0.
I changed use 5.010; to use use 5.010_001; in the code.
#!/usr/bin/env perl
use 5.010_001;
use strict;
use warnings;
package My::Base;
use mro;
our %conf;
sub new {
my ($class) = @_;
bless {} => $class;
}
sub configure {
my ($class, $opts) = @_;
{
no strict 'refs';
%{$class . '::conf'} = (%{$class . '::conf'}, %$opts);
}
$_->configure($opts) for @{mro::get_isarev($class)};
return;
}
package My::Trunk;
use parent -norequire, 'My::Base';
our %conf;
package My::Branch_A;
use parent -norequire, 'My::Trunk';
our %conf;
package My::Branch_B;
use parent -norequire, 'My::Trunk';
our %conf;
package main;
# Everything after here is for demo purposes only.
use Data::Dump;
say '*** Normal instantiation';
say 'My::Base object: ', My::Base::->new();
say 'My::Trunk object: ', My::Trunk::->new();
say 'My::Branch_A object: ', My::Branch_A::->new();
say 'My::Branch_B object: ', My::Branch_B::->new();
say "\n*** My::Base::->configure({A => 1});";
My::Base::->configure({A => 1});
_show_configs();
say "\n*** My::Trunk::->configure({B => 2, C => 3});";
My::Trunk::->configure({B => 2, C => 3});
_show_configs();
say "\n*** My::Branch_A::->configure({A => 'me', D => 4});";
My::Branch_A::->configure({A => 'me', D => 4});
_show_configs();
say "\n*** My::Branch_B::->configure({B => 'me', E => 5});";
My::Branch_B::->configure({B => 'me', E => 5});
_show_configs();
sub _show_configs {
say 'My::Base::conf';
dd \%My::Base::conf;
say 'My::Trunk::conf';
dd \%My::Trunk::conf;
say 'My::Branch_A::conf';
dd \%My::Branch_A::conf;
say 'My::Branch_B::conf';
dd \%My::Branch_B::conf;
}
Note that all lowercase package names are generally reserved for pragmata (e.g. strict, warnings, etc.).
I've replaced my::base with My::Base (and similarly for your other classes).
Output:
*** Normal instantiation
My::Base object: My::Base=HASH(0x800003c98)
My::Trunk object: My::Trunk=HASH(0x800003cc8)
My::Branch_A object: My::Branch_A=HASH(0x800003c98)
My::Branch_B object: My::Branch_B=HASH(0x800003cc8)
*** My::Base::->configure({A => 1});
My::Base::conf
{ A => 1 }
My::Trunk::conf
{ A => 1 }
My::Branch_A::conf
{ A => 1 }
My::Branch_B::conf
{ A => 1 }
*** My::Trunk::->configure({B => 2, C => 3});
My::Base::conf
{ A => 1 }
My::Trunk::conf
{ A => 1, B => 2, C => 3 }
My::Branch_A::conf
{ A => 1, B => 2, C => 3 }
My::Branch_B::conf
{ A => 1, B => 2, C => 3 }
*** My::Branch_A::->configure({A => 'me', D => 4});
My::Base::conf
{ A => 1 }
My::Trunk::conf
{ A => 1, B => 2, C => 3 }
My::Branch_A::conf
{ A => "me", B => 2, C => 3, D => 4 }
My::Branch_B::conf
{ A => 1, B => 2, C => 3 }
*** My::Branch_B::->configure({B => 'me', E => 5});
My::Base::conf
{ A => 1 }
My::Trunk::conf
{ A => 1, B => 2, C => 3 }
My::Branch_A::conf
{ A => "me", B => 2, C => 3, D => 4 }
My::Branch_B::conf
{ A => 1, B => "me", C => 3, E => 5 }
"I can't use Moose or any of the more advanced frameworks, i'm stuck with pretty basic perl unfortunately"
In that case, you may not have Data::Dump.
To run the demo, change that to Data::Dumper
and the dd ...; lines to print Dumper ...;.
See also: "perlootut - Object-Oriented Programming in Perl Tutorial"
and "perlobj - Perl object reference".