Beefy Boxes and Bandwidth Generously Provided by pair Networks
laziness, impatience, and hubris

Re^2: constraining the keys of a HashRef in Moose

by tomgracey (Beadle)
on Sep 02, 2013 at 08:53 UTC ( #1051907=note: print w/replies, xml ) Need Help??

in reply to Re: constraining the keys of a HashRef in Moose
in thread constraining the keys of a HashRef in Moose

Hi Tobyink,

thanks for your help earlier and for recommending the very useful Types::Standard and Types::ReadOnly modules - which I now believe you wrote (?) so i hope you dont mind me bugging you with a related question!

Suppose I have a module with the code you suggested:

my $colour_hash = Locked[ Dict[ red => Optional[Int], blue => Optional[Int], green => Optional[Int], ], ]; has scores => ( is => 'rw', isa => $colour_hash, default => sub{ {} }, coerce => 1, );

but now I have another package which inherits from this one. Is there any simple way to extend the list of allowed keys in the inherited class?

Replies are listed 'Best First'.
Re^3: constraining the keys of a HashRef in Moose
by tobyink (Abbot) on Sep 03, 2013 at 08:09 UTC

    I'd split out type constraint definitions into a separate type library module. Here's a quick example:

    use strict; use warnings; # is a shim for declaring multiple packages in the same file +. # It's on CPAN if you want it. Otherwise, just split them into separat +e # files. no thanks qw( MyApp::Types MyApp::Printer MyApp::Printer::ThreeColour MyApp::Printer::FourColour ); BEGIN { package MyApp::Types; use Type::Library -base, -declare => qw( ThreeColour FourColour ); use Type::Utils; use Types::Standard -types; use Types::ReadOnly -types; declare ThreeColour, as Locked[ Dict[ cyan => Optional[Num], magenta => Optional[Num], yellow => Optional[Num], ] ], coercion => 1; # black is referred to as "key" in CYMK printing. presumably becau +se # using a name that abbreviated to "B" would be confused with "blu +e". declare FourColour, as Locked[ Dict[ @{ ThreeColour->parent->wrapped->parameters }, # voodoo? key => Optional[Num], ] ], coercion => 1; }; BEGIN { package MyApp::Printer; use Moose::Role; # Let's assume the printer is only capable of printing one pixel. has pixel => (is => 'ro'); sub dump { require Data::Dumper; Data::Dumper::Dumper(@_); } }; BEGIN { package MyApp::Printer::ThreeColour; use MyApp::Types -types; use Moose; with qw(MyApp::Printer); has '+pixel' => (isa => ThreeColour, coerce => 1); }; BEGIN { package MyApp::Printer::FourColour; use MyApp::Types -types; use Moose; with qw(MyApp::Printer); has '+pixel' => (isa => FourColour, coerce => 1); }; my $printer = 'MyApp::Printer::FourColour'->new( pixel => { cyan => 9.4, magenta => 7, yellow => 4 }, ); print($printer->dump); $printer->pixel->{key} = 9; # ok print($printer->dump); $printer->pixel->{black} = 6; # dies
    use Moops; class Cow :rw { has name => (default => 'Ermintrude') }; say Cow->new->name
      Very informative and I appreciate you taking the time to explain... many thanks!

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://1051907]
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others romping around the Monastery: (3)
As of 2018-05-21 22:52 GMT
Find Nodes?
    Voting Booth?