{
    "content": [
        {
            "type": "text",
            "text": "# Type::Tiny::Manual::UsingWithMoo (perldoc)\n\n## NAME\n\nType::Tiny::Manual::UsingWithMoo - basic use of Type::Tiny with Moo\n\n## Sections\n\n- **NAME**\n- **MANUAL** (4 subsections)\n- **NEXT STEPS**\n- **NOTES**\n- **AUTHOR**\n- **COPYRIGHT AND LICENCE**\n- **DISCLAIMER OF WARRANTIES**\n\nUse structuredContent.sections for detailed options, examples, and full documentation.\n"
        }
    ],
    "structuredContent": {
        "command": "Type::Tiny::Manual::UsingWithMoo",
        "section": "",
        "mode": "perldoc",
        "summary": "Type::Tiny::Manual::UsingWithMoo - basic use of Type::Tiny with Moo",
        "synopsis": null,
        "tldr_summary": null,
        "tldr_examples": [],
        "tldr_source": null,
        "flags": [],
        "examples": [],
        "see_also": [],
        "section_outline": [
            {
                "name": "NAME",
                "lines": 2,
                "subsections": []
            },
            {
                "name": "MANUAL",
                "lines": 1,
                "subsections": [
                    {
                        "name": "Type Constraints",
                        "lines": 119
                    },
                    {
                        "name": "Parameterized Types",
                        "lines": 277
                    },
                    {
                        "name": "Type Coercions",
                        "lines": 84
                    },
                    {
                        "name": "Method Parameters",
                        "lines": 287
                    }
                ]
            },
            {
                "name": "NEXT STEPS",
                "lines": 18,
                "subsections": []
            },
            {
                "name": "NOTES",
                "lines": 20,
                "subsections": []
            },
            {
                "name": "AUTHOR",
                "lines": 2,
                "subsections": []
            },
            {
                "name": "COPYRIGHT AND LICENCE",
                "lines": 5,
                "subsections": []
            },
            {
                "name": "DISCLAIMER OF WARRANTIES",
                "lines": 4,
                "subsections": []
            }
        ],
        "sections": {
            "NAME": {
                "content": "Type::Tiny::Manual::UsingWithMoo - basic use of Type::Tiny with Moo\n",
                "subsections": []
            },
            "MANUAL": {
                "content": "",
                "subsections": [
                    {
                        "name": "Type Constraints",
                        "content": "Consider the following basic Moo class:\n\npackage Horse {\nuse Moo;\nuse namespace::autoclean;\n\nhas name       => ( is => 'ro' );\nhas gender     => ( is => 'ro' );\nhas age        => ( is => 'rw' );\nhas children   => ( is => 'ro', default => sub { [] } );\n}\n\nCode like this seems simple enough:\n\nmy $br = Horse->new(name => \"Bold Ruler\", gender => 'm', age => 16);\npush @{ $br->children },\nHorse->new(name => 'Secretariat', gender => 'm', age => 0);\n\nHowever, once you step away from very simple use of the class, things can start to go wrong.\nWhen we push a new horse onto \"@{ $br->children }\", we are assuming that \"$br->children\"\nreturned an arrayref.\n\nWhat if the code that created the $br horse had instantiated it like this?\n\nmy $br = Horse->new(name => \"Bold Ruler\", children => 'no');\n\nIt is for this reason that it's useful for the Horse class to perform some basic sanity-checking\non its own attributes.\n\npackage Horse {\nuse Moo;\nuse Types::Standard qw( Str Num ArrayRef );\nuse namespace::autoclean;\n\nhas name       => ( is => 'ro', isa => Str );\nhas gender     => ( is => 'ro', isa => Str );\nhas age        => ( is => 'rw', isa => Num );\nhas children   => (\nis      => 'ro',\nisa     => ArrayRef,\ndefault => sub { return  [] },\n);\n}\n\nNow, if you instantiate a horse like this, it will throw an error:\n\nmy $br = Horse->new(name => \"Bold Ruler\", children => 'no');\n\nThe first type constraint we used here was Str. This is type constraint that requires values to\nbe strings.\n\nNote that although \"undef\" is not a string, the empty string is still a string and you will\noften want to check that a string is non-empty. We could have done this:\n\nuse Types::Common::String qw( NonEmptyStr );\nhas name => ( is => 'ro', isa => NonEmptyStr );\n\nWhile most of the type constraints we will use in this manual are defined in Types::Standard,\nthe Types::Common::String type library also defines many useful type constraints.\n\nWe have required the horse's age to be a number. This is also a common, useful type constraint.\nIf we want to make sure it's a whole number, we could use:\n\nuse Types::Standard qw( Int );\nhas age => ( is => 'rw', isa => Int );\n\nOr because negative numbers make little sense as an age:\n\nuse Types::Common::Numeric qw( PositiveOrZeroInt );\nhas age => ( is => 'rw', isa => PositiveOrZeroInt );\n\nThe Types::Common::Numeric library defines many useful subtypes of Int and Num, such as\nPositiveInt and PositiveOrZeroInt.\n\nThe last type constraint we've used in this example is ArrayRef. This requires the value to be a\nreference to an array.\n\nTypes::Standard also provides HashRef and CodeRef type constraints. An example of using the\nlatter:\n\npackage Task {\nuse Moo;\nuse Types::Standard qw( CodeRef Bool );\nhas onsuccess => ( is => 'ro', isa => CodeRef );\nhas onfailure => ( is => 'ro', isa => CodeRef );\nhas finished   => ( is => 'ro', isa => Bool, default => 0 );\n...;\n}\n\nmy $task = Task->new(\nonsuccess => sub { ... },\nonfailure => sub { ... },\n...,\n);\n\nThe Bool type constraint accepts \"1\" as a true value, and \"0\", \"\", or undef as false values. No\nother values are accepted.\n\nThere exists an Object type constraint that accepts any blessed object.\n\npackage Horse {\nuse Moo;\nuse Types::Standard qw( Object );\nuse namespace::autoclean;\n\n...;  # name, gender, age, children\nhas father => ( is => 'ro', isa => Object );\nhas mother => ( is => 'ro', isa => Object );\n}\n\nFinally, another useful type constraint to know about is Any:\n\nuse Types::Standard qw( Any );\nhas stuff => ( is => 'rw', isa => Any );\n\nThis type constraint allows any value; it is essentially the same as not doing any type check,\nbut makes your intent clearer. Where possible, Type::Tiny will optimize away this type check, so\nit should have little (if any) impact on performance.\n"
                    },
                    {
                        "name": "Parameterized Types",
                        "content": "Let's imagine we want to keep track of our horse's race wins:\n\npackage Horse {\nuse Moo;\nuse Types::Standard qw( Str Num ArrayRef );\nuse namespace::autoclean;\n\n...;  # name, gender, age, children\nhas wins => (\nis      => 'ro',\nisa     => ArrayRef,\ndefault => sub { return [] },\n);\n}\n\nWe can create a horse like this:\n\nmy $br = Horse->new(\nname    => \"Bold Ruler\",\ngender  => 'm',\nage     => 4,\nwins    => [\"Futurity Stakes 1956\", \"Juvenile Stakes 1956\"],\n);\n\nThe list of wins is an arrayref of strings. The ArrayRef type constraint prevents it from being\nset to a hashref, for example, but it doesn't ensure that everything in the arrayref is a\nstring. To do that, we need to parameterize the type constraint:\n\nhas wins => (\nis      => 'ro',\nisa     => ArrayRef[Str],\ndefault => sub { return [] },\n);\n\nThanks to the ArrayRef[Str] parameterized type, the constructor will throw an error if the\narrayref you pass to it contains anything non-string.\n\nAn alternative way of writing this is:\n\nhas wins => (\nis      => 'ro',\nisa     => ArrayRef->of(Str),\ndefault => sub { return [] },\n);\n\nWhich way you choose is largely a style preference. TIMTOWTDI!\n\nNote that although the constructor and any setter/accessor method will perform type checks, it\nis possible to bypass them using:\n\npush @{ $br->wins }, $notastring;\n\nThe constructor isn't being called here, and although the accessor *is* being called, it's being\ncalled as a reader, not a writer, so never gets an opportunity to inspect the value being added.\n(It is possible to use \"tie\" to solve this, but that will be covered later.)\n\nAnd of course, if you directly poke at the underlying hashref of the object, all bets are off:\n\n$br->{wins} = $notanarrayref;\n\nSo type constraints do have limitations. Careful API design (and not circumventing the proper\nAPI) can help.\n\nThe HashRef type constraint can also be parameterized:\n\npackage Design {\nuse Moo;\nuse Types::Standard qw( HashRef Str );\nhas colours => ( is => 'ro', isa => HashRef[Str] );\n}\n\nmy $eiffel65 = Design->new(\ncolours => { house => \"blue\", littlewindow => \"blue\" },\n);\n\nThe HashRef[Str] type constraint ensures the *values* of the hashref are strings; it doesn't\ncheck the keys of the hashref because keys in Perl hashes are always strings!\n\nIf you do need to constrain the keys, it is possible to use a parameterized Map constraint:\n\nuse Types::Common::String qw( NonEmptyStr );\nuse Types::Standard qw( Map );\nhas colours => ( is => 'ro', isa => Map[NonEmptyStr, NonEmptyStr] );\n\nMap takes two parameters; the first is a type to check keys against and the second is a type to\ncheck values against.\n\nAnother useful type constraint is the Tuple type constraint.\n\nuse Types::Standard qw( ArrayRef Tuple );\nuse Types::Common::Numeric qw( PositiveInt );\nuse Types::Common::String qw( NonEmptyStr );\n\nhas wins => (\nis      => 'ro',\nisa     => ArrayRef[ Tuple[PositiveInt, NonEmptyStr] ],\ndefault => sub { return [] },\n);\n\nThe Tuple[PositiveInt, NonEmptyStr] type constraint checks that a value is a two-element\narrayref where the first element is a positive integer and the second element is a non-empty\nstring. For example:\n\nmy $br = Horse->new(\nname    => \"Bold Ruler\",\nwins    => [\n[ 1956, \"Futurity Stakes\" ],\n[ 1956, \"Juvenile Stakes\" ],\n],\n);\n\nAs you can see, parameterized type constraints may be nested to arbitrary depth, though of\ncourse the more detailed your checks become, the slower they will perform.\n\nIt is possible to have tuples with variable length. For example, we may wish to include the\njockey name in our race wins when it is known.\n\nuse Types::Standard qw( ArrayRef Tuple Optional );\nuse Types::Common::Numeric qw( PositiveInt );\nuse Types::Common::String qw( NonEmptyStr );\n\nhas wins => (\nis      => 'ro',\nisa     => ArrayRef[\nTuple[ PositiveInt, NonEmptyStr, Optional[NonEmptyStr] ]\n],\ndefault => sub { return [] },\n);\n\nThe third element will be checked if it is present, but forgiven if it is absent.\n\nOr we could just allow tuples to contain an arbitrary list of strings after the year and race\nname:\n\nuse Types::Standard qw( ArrayRef Tuple Str slurpy );\nuse Types::Common::Numeric qw( PositiveInt );\nuse Types::Common::String qw( NonEmptyStr );\n\nhas wins => (\nis      => 'ro',\nisa     => ArrayRef[\nTuple[ PositiveInt, NonEmptyStr, slurpy ArrayRef[Str] ]\n],\ndefault => sub { return [] },\n);\n\nThe \"slurpy\" indicator will \"slurp\" all the remaining items in the tuple into an arrayref and\ncheck it against ArrayRef[Str].\n\nIt's even possible to do this:\n\nuse Types::Standard qw( ArrayRef Tuple Any slurpy );\nuse Types::Common::Numeric qw( PositiveInt );\nuse Types::Common::String qw( NonEmptyStr );\n\nhas wins => (\nis      => 'ro',\nisa     => ArrayRef[\nTuple[ PositiveInt, NonEmptyStr, slurpy Any ]\n],\ndefault => sub { return [] },\n);\n\nWith this type constraint, any elements after the first two will be slurped into an arrayref and\nwe don't check that arrayref at all. (In fact, the implementation of the Tuple type is smart\nenough to not bother creating the temporary arrayref to check.)\n\nDict is the equivalent of Tuple for checking values of hashrefs.\n\nuse Types::Standard qw( ArrayRef Dict Optional );\nuse Types::Common::Numeric qw( PositiveInt );\nuse Types::Common::String qw( NonEmptyStr );\n\nhas wins => (\nis      => 'ro',\nisa     => ArrayRef[\nDict[\nyear    => PositiveInt,\nrace    => NonEmptyStr,\njockey  => Optional[NonEmptyStr],\n],\n],\ndefault => sub { return [] },\n);\n\nAn example of using it:\n\nmy $br = Horse->new(\nname    => \"Bold Ruler\",\nwins    => [\n{ year => 1956, race => \"Futurity Stakes\", jockey => \"Eddie\" },\n{ year => 1956, race => \"Juvenile Stakes\" },\n],\n);\n\nThe slurpy indicator does work for Dict too:\n\nDict[\nyear    => PositiveInt,\nrace    => NonEmptyStr,\njockey  => Optional[NonEmptyStr],\nslurpy HashRef[Str],  # other Str values allowed\n]\n\nAnd \"slurpy Any\" means what you probably think it means:\n\nDict[\nyear    => PositiveInt,\nrace    => NonEmptyStr,\njockey  => Optional[NonEmptyStr],\nslurpy Any,  # allow hashref to contain absolutely anything else\n]\n\nGoing back to our first example, there's an opportunity to refine our ArrayRef constraint:\n\npackage Horse {\nuse Moo;\nuse Types::Standard qw( Str Num ArrayRef );\nuse namespace::autoclean;\n\nhas name       => ( is => 'ro', isa => Str );\nhas gender     => ( is => 'ro', isa => Str );\nhas age        => ( is => 'rw', isa => Num );\nhas children   => (\nis      => 'ro',\nisa     => ArrayRef[ InstanceOf[\"Horse\"] ],\ndefault => sub { return [] },\n);\n}\n\nThe InstanceOf[\"Horse\"] type constraint checks that a value is a blessed object in the Horse\nclass. So the horse's children should be an arrayref of other Horse objects.\n\nInternally it just checks \"$->isa(\"Horse\")\" on each item in the arrayref.\n\nIt is sometimes useful to instead check \"$->DOES($role)\" or \"$->can($method)\" on an object.\nFor example:\n\npackage MyAPI::Client {\nuse Moo;\nuse Types::Standard qw( HasMethods );\n\nhas ua => (is => 'ro', isa => HasMethods[\"get\", \"post\"] );\n}\n\nThe ConsumerOf and HasMethods parameterizable types allow you to easily check roles and methods\nof objects.\n\nThe Enum parameterizable type allows you to accept a more limited set of string values. For\nexample:\n\nuse Types::Standard qw( Enum );\nhas gender => ( is => 'ro', isa => Enum[\"m\",\"f\"] );\n\nOr if you want a little more flexibility, you can use StrMatch which allows you to test strings\nagainst a regular expression:\n\nuse Types::Standard qw( StrMatch );\nhas gender => ( is => 'ro', isa => StrMatch[qr/^[MF]/i] );\n\nOr StrLength to check the maximum and minimum length of a string:\n\nuse Types::Common::String qw( StrLength );\nhas name => ( is => 'ro', isa => StrLength[3, 100] );\n\nThe maximum can be omitted.\n\nSimilarly, the maximum and minimum values for a numeric type can be expressed using IntRange and\nNumRange:\n\nuse Types::Common::Numeric qw( IntRange );\n# values over 200 are probably an input error\nhas age => ( is => 'ro', isa => IntRange[0, 200] );\n\nParameterized type constraints are one of the most powerful features of Type::Tiny, allowing a\nsmall set of constraints to be combined in useful ways.\n"
                    },
                    {
                        "name": "Type Coercions",
                        "content": "It is often good practice to be liberal in what you accept.\n\npackage Horse {\nuse Moo;\nuse Types::Standard qw( Str Num ArrayRef Bool );\nuse namespace::autoclean;\n\n...;  # name, gender, age, children, wins\nhas isalive => ( is => 'rw', isa => Bool, coerce => 1 );\n}\n\nThe \"coerce\" option indicates that if a value is given which *does not* pass the Bool type\nconstraint, then it should be coerced (converted) into something that does.\n\nThe definition of Bool says that to convert a non-boolean to a bool, you just do \"!! $nonbool\".\nSo all of the following will be living horses:\n\nHorse->new(isalive => 42)\nHorse->new(isalive => [])\nHorse->new(isalive => \"false\") # in Perl, string \"false\" is true!\n\nBool is the only type constraint in Types::Standard that has a coercion defined for it. The\nNumericCode, UpperCaseStr, LowerCaseStr, UpperCaseSimpleStr, and LowerCaseSimpleStr types from\nTypes::Common::String also have conversions defined.\n\nThe other built-in constraints do not define any coercions because it would be hard to agree on\nwhat it means to coerce from, say, a HashRef to an ArrayRef. Do we keep the keys? The values?\nBoth?\n\nBut it is pretty simple to add your own coercions!\n\nuse Types::Standard qw( ArrayRef HashRef Str );\nhas things => (\nis     => 'rw',\nisa    => ArrayRef->pluscoercions(\nHashRef,     sub { [ values %$ ] },\nStr,         sub { [ split /;/, $ ] },\n),\ncoerce => 1,\n);\n\n(Don't ever forget the \"coerce => 1\"!)\n\nIf a hashref is provided, the values will be used, and if a string is provided, it will be split\non the semicolon. Of course, if an arrayref if provided, it already passes the type constraint,\nso no conversion is necessary.\n\nThe coercions should be pairs of \"from types\" and code to coerce the value. The code can be a\ncoderef (as above) or just string of Perl code (as below). Strings of Perl code can usually be\noptimized better by Type::Tiny's internals, so are generally preferred. Thanks to Perl's\n\"q{...}\" operator, they can look just as clean and pretty as coderefs.\n\nuse Types::Standard qw( ArrayRef HashRef Str );\nhas things => (\nis     => 'rw',\nisa    => ArrayRef->pluscoercions(\nHashRef,     q{ values %$ },\nStr,         q{ [ split /;/, $ ] },\n),\ncoerce => 1,\n);\n\nCoercions are deeply applied automatically, so the following will do what you expect.\n\nhas inputs => (\nis     => 'ro',\nisa    => ArrayRef->of(Bool),\ncoerce => 1\n);\n\nI am, of course, assuming you expect something like:\n\nmy $coerced = [ map { !!$ } @$orig ];\n\nIf you were assuming that, congratulations! We are on the same wavelength.\n\nAnd of course you can still add more coercions to the inherited ones...\n\nhas inputs => (\nis     => 'ro',\nisa    => ArrayRef->of(Bool)->pluscoercions(Str, sub {...}),\ncoerce => 1\n);\n"
                    },
                    {
                        "name": "Method Parameters",
                        "content": "So far we have just concentrated on the definition of object attributes, but type constraints\nare also useful to validate method parameters.\n\nLet's remember our attribute for keeping track of a horse's race wins:\n\nuse Types::Standard qw( ArrayRef Tuple Optional );\nuse Types::Common::Numeric qw( PositiveInt );\nuse Types::Common::String qw( NonEmptyStr );\n\nhas wins => (\nis      => 'ro',\nisa     => ArrayRef[\nTuple[ PositiveInt, NonEmptyStr, Optional[NonEmptyStr] ]\n],\ndefault => sub { return [] },\n);\n\nBecause we don't trust outside code to push new entries onto this array, let's define a method\nin our class to do it.\n\npackage Horse {\n...;\n\nsub addwin {\nmy $self = shift;\nmy ($year, $race, $jockey) = @;\nmy $win = [\n$year,\n$race,\n$jockey ? $jockey : (),\n];\npush @{ $self->wins }, $win;\nreturn $self;\n}\n}\n\nThis works pretty well, but we're still not actually checking the values of $year, $race, and\n$jockey. Let's use Type::Params for that:\n\npackage Horse {\nuse Types::Common::Numeric qw( PositiveInt );\nuse Types::Common::String qw( NonEmptyStr );\nuse Type::Params qw( compile );\n...;\n\nsub addwin {\nstate $check = compile(\nPositiveInt,\nNonEmptyStr,\nNonEmptyStr, { optional => 1 },\n);\n\nmy $self = shift;\nmy ($year, $race, $jockey) = $check->(@);\nmy $win = [\n$year,\n$race,\n$jockey ? $jockey : (),\n];\npush @{ $self->wins }, $win;\nreturn $self;\n}\n}\n\nThe first time this method is called, it will compile a coderef called $check. Then every time\nit is run, $check will be called to check the method's parameters. It will throw an exception if\nthey fail. $check will also perform coercions if types have them (and you don't even need to\nremember \"coerce => 1\"; it's always automatic) and can even add in defaults:\n\nstate $check = compile(\nPositiveInt,\nNonEmptyStr,\nNonEmptyStr, { default => sub { \"Eddie\" } },\n);\n\nOn older versions of Perl (prior to 5.10), \"state\" variables are not available. A workaround is\nto replace this:\n\nsub foo {\nstate $x = bar();\n...;\n}\n\nWith this:\n\n{         # outer braces prevent other subs seeing $x\nmy $x;  # declare $x before sub foo()\nsub foo {\n$x = bar();\n...;\n}\n}\n\n(While we're having a general Perl syntax lesson, I'll note that &$check with an ampersand and\nno parentheses is a shortcut for \"$check->(@)\" and actually runs slightly faster because it\nreuses the @ array for the called coderef. A lot of people dislike calling subs with an\nampersand, so we will stick to the \"$check->(@)\" syntax in these examples. But do consider\nusing the shortcut!)\n\nThe generalized syntax for \"compile\" is:\n\nstate $check = compile(\n\\%generaloptions,\nTypeForFirstParam,  \\%optionsforfirstparam,\nTypeForSecondParam, \\%optionsforsecondparam,\n...,\n);\n\nAs a shortcut for the \"{ optional => 1 }}\" option, you can just use Optional like in Tuple.\n\nstate $check = compile(\nPositiveInt,\nNonEmptyStr,\nOptional[NonEmptyStr],\n);\n\nYou can also use 0 and 1 as shortcuts for Optional[Any] and Any. The following checks that the\nfirst parameter is a positive integer, the second parameter is required (but doesn't care what\nvalue it is) and the third parameter is allowed but not required.\n\nstate $check = compile(PositiveInt, 1, 0);\n\nIt is possible to accept a variable number of values using \"slurpy\":\n\npackage Horse {\nuse Types::Common::Numeric qw( PositiveInt );\nuse Types::Common::String qw( NonEmptyStr );\nuse Types::Standard qw( ArrayRef slurpy );\nuse Type::Params qw( compile );\n...;\n\nsub addwinsforyear {\nstate $check = compile(\nPositiveInt,\nslurpy ArrayRef[NonEmptyStr],\n);\n\nmy $self = shift;\nmy ($year, $races) = $check->(@);\nfor my $race (@$races) {\npush @{ $self->wins }, [$year, $win];\n}\nreturn $self;\n}\n}\n\nIt would be called like this:\n\n$boldruler->addwinsforyear(\n1956,\n\"Futurity Stakes\",\n\"Juvenile Stakes\",\n);\n\nThe additional parameters are slurped into an arrayref and checked against\nArrayRef[NonEmptyStr].\n\nOptional parameters are only allowed after required parameters, and slurpy parameters are only\nallowed at the end. (And there can only be a at most one slurpy parameter!)\n\nFor methods that accept more than one or two parameters, it is often a good idea to provide them\nas a hash. For example:\n\n$horse->addwin(\nyear    => 1956,\nrace    => \"Futurity Stakes\",\njockey  => \"Eddie\",\n);\n\nThis can make your code more readable.\n\nTo accept named parameters, use \"compilenamed\" instead of \"compile\".\n\npackage Horse {\nuse Types::Common::Numeric qw( PositiveInt );\nuse Types::Common::String qw( NonEmptyStr );\nuse Type::Params qw( compilenamed );\n...;\n\nsub addwin {\nstate $check = compilenamed(\nyear    => PositiveInt,\nrace    => NonEmptyStr,\njockey  => NonEmptyStr, { optional => 1 },\n);\n\nmy $self = shift;\nmy $args = $check->(@);\nmy $win = [\n$args->{year},\n$args->{race},\nexists($args->{jockey}) ? $args->{jockey} : (),\n];\npush @{ $self->wins }, $win;\nreturn $self;\n}\n}\n\n\"compile\" and \"compilenamed\" work pretty much the same, except the latter accepts named\nparameters instead of positional, and returns a hashref.\n\nIt will automatically allow for a hashref to be provided instead of a full hash. The following\nboth work, but the $args variable will always be given a hashref.\n\n$horse->addwin({\nyear    => 1956,\nrace    => \"Juvenile Stakes\",\n});\n$horse->addwin(\nyear    => 1956,\nrace    => \"Futurity Stakes\",\njockey  => \"Eddie\",\n);\n\nWell... I say \"always\" but you can tell \"compilenamed\" to accept named parameters but return a\npositional list of parameters:\n\npackage Horse {\nuse Types::Common::Numeric qw( PositiveInt );\nuse Types::Common::String qw( NonEmptyStr );\nuse Type::Params qw( compilenamed );\n...;\n\nsub addwin {\nstate $check = compilenamed(\n{ namedtolist => 1 },\nyear    => PositiveInt,\nrace    => NonEmptyStr,\njockey  => NonEmptyStr, { optional => 1 },\n);\n\nmy $self = shift;\nmy ($year, $race, $jockey) = $check->(@);\nmy $win = [\n$year,\n$race,\n$jockey ? $jockey : (),\n];\npush @{ $self->wins }, $win;\nreturn $self;\n}\n}\n\nOptional and slurpy named parameters are supported as you'd expect.\n\nWith named parameters, it can be easy to misspell keys in your method definition. For example:\n\nmy $win = [\n$args->{year},\n$args->{race},\nexists($args->{jockee}) ? $args->{jockey} : (),\n];\n\nNote \"jockee\"! This can lead to hard-to-find bugs. There's a \"compilenamedoo\" function which\nmay help and can lead to cleaner code.\n\npackage Horse {\nuse Types::Common::Numeric qw( PositiveInt );\nuse Types::Common::String qw( NonEmptyStr );\nuse Type::Params qw( compilenamedoo );\n...;\n\nsub addwin {\nstate $check = compilenamedoo(\nyear    => PositiveInt,\nrace    => NonEmptyStr,\njockey  => NonEmptyStr, { optional => 1 },\n);\n\nmy $self = shift;\nmy $args = $check->(@);\nmy $win = [\n$args->year,\n$args->race,\n$args->hasjockey ? $args->jockey : (),\n];\npush @{ $self->wins }, $win;\nreturn $self;\n}\n}\n\nNow $args is a blessed object that you can call methods on. There is of course a performance\npenalty for this, but it's surprisingly small.\n\nFor more information on Type::Params, and third-party alternatives, see\nType::Tiny::Manual::Params.\n"
                    }
                ]
            },
            "NEXT STEPS": {
                "content": "Congratulations! I know this was probably a lot to take in, but you've covered all of the\nessentials.\n\nYou can now set type constraints and coercions for attributes and method parameters in Moo! You\nare familiar with a lot of the most important and useful type constraints and understand\nparameterization and how it can be used to build more specific type constraints.\n\n(And I'll let you in on a secret. Using Type::Tiny with Moose or Mouse instead of Moo is exactly\nthe same. You can just replace \"use Moo\" with \"use Moose\" in any of these examples and they\nshould work fine!)\n\nHere's your next step:\n\n*   Type::Tiny::Manual::UsingWithMoo2\n\nAdvanced use of Type::Tiny with Moo, including unions and intersections, \"stringifiesto\",\n\"numifiesto\", \"withattributevalues\", and \"where\".\n",
                "subsections": []
            },
            "NOTES": {
                "content": "On very old versions of Moo \"coerce => 1\" is not supported. Instead you will need to provide a\ncoderef or object overloading \"&{}\" to coerce. Type::Tiny can provide you with an overloaded\nobject.\n\npackage Horse {\nuse Moo;\nuse Types::Standard qw( Str Num ArrayRef Bool );\nuse namespace::autoclean;\n\n...;  # name, gender, age, children, wins\nhas isalive => (\nis      => 'rw',\nisa     => Bool,\ncoerce  => Bool->coercion,  # overloaded object\n);\n}\n\nIf you have a very old version of Moo, please upgrade to at least Moo 1.006000 which was the\nversion that added support for \"coerce => 1\".\n",
                "subsections": []
            },
            "AUTHOR": {
                "content": "Toby Inkster <tobyink@cpan.org>.\n",
                "subsections": []
            },
            "COPYRIGHT AND LICENCE": {
                "content": "This software is copyright (c) 2013-2014, 2017-2021 by Toby Inkster.\n\nThis is free software; you can redistribute it and/or modify it under the same terms as the Perl\n5 programming language system itself.\n",
                "subsections": []
            },
            "DISCLAIMER OF WARRANTIES": {
                "content": "THIS PACKAGE IS PROVIDED \"AS IS\" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,\nWITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR\nPURPOSE.\n",
                "subsections": []
            }
        }
    }
}