Beefy Boxes and Bandwidth Generously Provided by pair Networks
Come for the quick hacks, stay for the epiphanies.
 
PerlMonks  

Re^2: Inheritable configuration options.... but with default values?

by LanX (Saint)
on Feb 20, 2020 at 23:06 UTC ( [id://11113287]=note: print w/replies, xml ) Need Help??


in reply to Re: Inheritable configuration options.... but with default values?
in thread Inheritable configuration options.... but with default values?

I'm confused, in my book is new() reserved for object constructors not classes.

Inheritance for classes should be easier done by

use strict; use warnings; use Data::Dump qw/pp dd/; package Class1 { our %cfg = (a => 1, b=>2); sub cfg { %cfg } }; package Class2 { use parent -norequire, 'Class1'; our %cfg = ( %Class1::cfg, a=>11,c=>33 ); }; package Class3 { use parent -norequire, 'Class2'; our %cfg = ( %Class2::cfg, b=> 222 ); }; pp \%Class1::cfg, \%Class2::cfg, \%Class3::cfg; # **** THIS DOESN'T WORK package Class2b { use parent -norequire, 'Class1'; our %cfg = ( SUPER->cfg(), a=>11,c=>33 ); }; pp {Class1->cfg()}, \%Class2b::cfg;

Please note that I couldn't make it work with SUPER, ( but I'm no SUPER expert anyway ;-)

(
  { a => 1, b => 2 },
  { a => 11, b => 2, c => 33 },
  { a => 11, b => 222, c => 33 },
)
Can't locate object method "cfg" via package "SUPER" (perhaps you forgot to load "SUPER"?) at d:/tmp/pm/class_cfg.pl line 32.

Compilation exited abnormally with code 255 at Fri Feb 21 00:04:51

edit

ah I misread perlobj

> The SUPER modifier can only be used for method calls. You can't use it for regular subroutine calls or class methods:

update

This works, albeit with ugly syntax.

... package Class2b { use parent -norequire, 'Class1'; our %cfg = ( __PACKAGE__->SUPER::cfg(), a=>11,c=>33,n=>'2b' ); }; pp \%Class2b::cfg;

{ a => 11, b => 2, c => 33, n => "2b" }

Cheers Rolf
(addicted to the Perl Programming Language :)
Wikisyntax for the Monastery

Replies are listed 'Best First'.
Re^3: Inheritable configuration options.... but with default values?
by bliako (Monsignor) on Feb 21, 2020 at 00:03 UTC

    You are using package variables (what other languages call static) and in your update you have the right syntax. If you had an object, the way to access its parent's package variable is stated in perlobj, at the place you quoted it: for a static method: $self->SUPER::save(); and for a package variable %{$self->SUPER::cfg};

    But package variables are not "object variables" or member variables (?whatever?). It would be better to store %cfg into $self's hash for at least one reason: inheritance is taken care by Perl for free. Whereas in your case, Perl takes care of the inheritance of Class1 into Class2 and YOU MUST (not forget to) take care of the inheritance of Class1's package variables. That's a lot of boiler work (for me ;) ).

    related: https://stackoverflow.com/questions/3109672/how-to-make-a-hash-available-in-another-module and Perl Inheritance & module variables . The latter in particular is similar to what you have shown.

      > But package variables are not "object variables" or member variables (?whatever?)

      yeah, but I tought that's what the OP asked for !?!

      > > > Basically i have a series of classes and subclasses, each level adding a bit more functionality to its parent and in each class i have behaviour which can be modified by configuration options which are specific to that class

      see? Class not Object.

      > That's a lot of boiler work (for me ;) ).

      Well my code was shorter than yours. ;)

      (...and I'm sure this could be even shortened further with some sugar)

      > and for a package variable %{$self->SUPER::cfg};

      I doubt it, according to the docs cfg here - i.e. the part after SUPER:: - must be a sub in the super class.

      Cheers Rolf
      (addicted to the Perl Programming Language :)
      Wikisyntax for the Monastery

Re^3: Inheritable configuration options.... but with default values?
by LanX (Saint) on Feb 21, 2020 at 00:45 UTC
    TIMTOWTDI

    use strict; use warnings; use Data::Dump qw/pp dd/; package Class1 { use constant cfg => { a => 1 }; }; package Class2 { use parent -norequire, 'Class1'; use constant cfg => { %{__PACKAGE__->SUPER::cfg}, b => 2 }; }; package Class3 { use parent -norequire, 'Class2'; use constant cfg => { %{__PACKAGE__->SUPER::cfg}, c => 3 }; sub meth { warn "a is ",cfg->{a} } }; pp Class1::cfg, Class2::cfg, Class3::cfg ; Class3->meth();
    ({ a => 1 }, { a => 1, b => 2 }, { a => 1, b => 2, c => 3 })
    a is 1 at d:/tmp/pm/class_cfg.pl line 18.
    

    Cheers Rolf
    (addicted to the Perl Programming Language :)
    Wikisyntax for the Monastery

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://11113287]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others lurking in the Monastery: (3)
As of 2024-04-25 12:51 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found