These keys are LTA
While toying around with enums as boolean options to a routine, i found the default error message less then awesome.
Constraint type check failed for parameter '@options'
It would be hard to be even less specific. Let’s create a few exceptions to tell what is going on when things go wrong.
class X::Paramenter::Exclusive is Exception { has $.type; method message { "Parameters of {$.type.perl} are mutual exclusive" } }
Now we can check if options of Find::Type
are exclusive and complain accordingly.
&& ( exclusive-argument(@options, Find::Type) or fail X::Paramenter::Exclusive.new(type => Find::Type) ) class X::Parameter::UnrecognisedOption is Exception { has $.type; has $.unrecognised; method message { "Option { $.unrecognised } not any of { $.type.map({ (.^name ~ '::') xx * Z~ .enums.keys.flat }).flat.join(', ') }" } }
Since enums are containers for types and those got names we can use set operators to check and single out none matching options (basically anything the +@options
slurps up we don’t know).
or fail X::Parameter::UnrecognisedOption.new(type => (Find::Type, Find::Options), unrecognised => .item ∖ (|Find::Type::.values, |Find::Options::.values) )
Stitching the error message together is a bit more involved because we can get a list of all enum keys in a given enum but those don’t know their qualified name. We have to prefix with the enum name and ::
by hand.
class X::Parameter::UnrecognisedOption is Exception { has $.type; has $.unrecognised; method message { "Option { $.unrecognised } not any of { $.type.map: { (.^name ~ '::') xx * Z~ .enums.keys.flat } }" } }
This results in a much more awesome error message:
Option 42 not any of Type::File, Type::Dir, Type::Symlink, Options::Recursive, Options::Keep-going
This looks all quite regular. We have a slurpy that is kind of parameterised with one or many enums and those enums may have a flag telling if they act like radio buttons. Sounds like this idiom would fit nicely into a module.
-
September 26, 2016 at 23:052016.39 Keys To Cover Moar Tests | Weekly changes in and around Perl 6