karlgoethebier has asked for the wisdom of the Perl Monks concerning the following question:

Hi all,

because of boredom and for curiousity and learning purposes i wrote this little simple sketch:

package Karl::Constructor { use Role::Tiny; use feature qw(say); say __PACKAGE__; sub new { my ( $class, $self ) = @_; bless $self, $class; $self; } 1; } package CarConstructor { use feature qw(say); use Role::Tiny; use Role::Tiny::With; with qw(Karl::Constructor); requires qw(brand model color hp price); say __PACKAGE__; 1; } package CarConfigurator { use Role::Tiny::With; use feature qw(say); with qw(CarConstructor SomePlugin); say __PACKAGE__; sub brand { shift->{brand}; } sub color { shift->{color}; } sub hp { shift->{hp}; } sub price { shift->{price}; } sub model { shift->{model}; } 1; } package SomePlugin { use Role::Tiny; use feature qw(say); say __PACKAGE__; before brand => sub { say q(Tricky Dick!) }; around brand => sub { uc &{ (shift) }; }; after brand => sub { say q(Too late!); }; sub extra { shift->{extra}; } 1; } #!/usr/bin/env perl use strict; use warnings; use CarConfigurator; use feature qw(say); say __PACKAGE__; my $car = CarConfigurator->new( { brand => q(Porsche), color => q(Black), model => q(911), hp => q(>300), price => q(Don't ask), extra => q(Wine), } ); say qq(Brand:\t), $car->brand; say qq(Model:\t), $car->model; say qq(Color:\t), $car->color; say qq(hp:\t), $car->hp; say qq(Price:\t), $car->price; say qq(Extra:\t), $car->extra; __END__ karls-mac-mini:playground karl$ ./run.pl Karl::Constructor CarConstructor SomePlugin CarConfigurator main Tricky Dick! Too late! Brand: PORSCHE Model: 911 Color: Black hp: >300 Price: Don't ask Extra: Wine

It looks like it works as expected and it seems to be relatively easy to change the behaviour of the whole construct.

Any hints, thoughts, critics etc. are appreciated.

Thanks and best regards, Karl

P.S.: Yes, the naming of the classes/roles could be much better.

«The Crux of the Biscuit is the Apostrophe»

perl -MCrypt::CBC -E 'say Crypt::CBC->new(-key=>'kgb',-cipher=>"Blowfish")->decrypt_hex($ENV{KARL});'Help

Replies are listed 'Best First'.
Re: What About Providing Constructors in Roles?
by choroba (Cardinal) on Dec 21, 2017 at 15:34 UTC
    The constructor you provided does nothing. Things might get more interesting if the constructor had parameters - do you want to use the same parameters for all the classes consuming the role? What about classes based on Moo/Moose where the constructor is provided by the framework with parameters derived from the public non-lazy attributes?

    What are you trying to achieve?

    ($q=q:Sq=~/;[c](.)(.)/;chr(-||-|5+lengthSq)`"S|oS2"`map{chr |+ord }map{substrSq`S_+|`|}3E|-|`7**2-3:)=~y+S|`+$1,++print+eval$q,q,a,
      "The constructor you provided does nothing..."

      Yes and no. At least it returns the blessed ref.

      "...if the constructor had parameters..."

      But it has parameters, doesn't it?

      "...use the same parameters for all the classes consuming the role..."

      No. And yes. Just passing in the hash ref.

      "...classes based on Moo/Moose..."

      This is what i wanted to avoid.

      "...trying to achieve?"

      Nothing. This is just an exercise.

      Basic idea:

      1. Provide a "generic" constructor (first role)
      2. Specify attributes (next role)
      3. Specify accessors/behaviour (class)
      4. Modify attributes/accessors/behaviour (plugin)

      Best regards, Karl

      «The Crux of the Biscuit is the Apostrophe»

      perl -MCrypt::CBC -E 'say Crypt::CBC->new(-key=>'kgb',-cipher=>"Blowfish")->decrypt_hex($ENV{KARL});'Help

Re: What About Providing Constructors in Roles?
by 1nickt (Canon) on Dec 21, 2017 at 14:22 UTC

    Hi Karl, the standard practice I believe is to use a Role for something a thing *does*, not what it *is*, which is why Roles don't have constructors normally. FWIW (approx $0.02).


    The way forward always starts with a minimal test.
      "...Roles don't have constructors normally..."

      Hi Nick, i was sure that someone would post something like this ;-)

      But you are right: They don't. But in this case they provide them. Having a constructor or providing one is a different thing IMHO. Perhaps my English is still too bad to explain the difference exactly.

      Best regards, Karl

      «The Crux of the Biscuit is the Apostrophe»

      perl -MCrypt::CBC -E 'say Crypt::CBC->new(-key=>'kgb',-cipher=>"Blowfish")->decrypt_hex($ENV{KARL});'Help

        Your English is fine! The code, too. Your intention is what's unclear ;-)


        The way forward always starts with a minimal test.