{
    "content": [
        {
            "type": "text",
            "text": "# Type::Tiny::Manual::UsingWithMoo3 (perldoc)\n\n## NAME\n\nType::Tiny::Manual::UsingWithMoo3 - alternative use of Type::Tiny with Moo\n\n## Sections\n\n- **NAME**\n- **MANUAL** (4 subsections)\n- **NEXT STEPS**\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::UsingWithMoo3",
        "section": "",
        "mode": "perldoc",
        "summary": "Type::Tiny::Manual::UsingWithMoo3 - alternative 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 Registries",
                        "lines": 111
                    },
                    {
                        "name": "Importing Functions",
                        "lines": 113
                    },
                    {
                        "name": "Exporting Parameterized Types",
                        "lines": 26
                    },
                    {
                        "name": "dwim_type",
                        "lines": 10
                    }
                ]
            },
            {
                "name": "NEXT STEPS",
                "lines": 9,
                "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::UsingWithMoo3 - alternative use of Type::Tiny with Moo\n",
                "subsections": []
            },
            "MANUAL": {
                "content": "",
                "subsections": [
                    {
                        "name": "Type Registries",
                        "content": "In all the examples so far, we have imported a collection of type constraints into each class:\n\npackage Horse {\nuse Moo;\nuse Types::Standard qw( Str ArrayRef HashRef Int Any InstanceOf );\nuse Types::Common::Numeric qw( PositiveInt );\nuse Types::Common::String qw( NonEmptyStr );\n\nhas name    => ( is => 'ro', isa => Str );\nhas father  => ( is => 'ro', isa => InstanceOf[\"Horse\"] );\n...;\n}\n\nThis creates a bunch of subs in the Horse namespace, one for each type. We've used\nnamespace::autoclean to clean these up later.\n\nBut it is also possible to avoid pulling all these into the Horse namespace. Instead we'll use a\ntype registry:\n\npackage Horse {\nuse Moo;\nuse Type::Registry qw( t );\n\nt->addtypes('-Standard');\nt->addtypes('-Common::String');\nt->addtypes('-Common::Numeric');\n\nt->aliastype('InstanceOf[\"Horse\"]' => 'Horsey');\n\nhas name     => ( is => 'ro', isa => t('Str') );\nhas father   => ( is => 'ro', isa => t('Horsey') );\nhas mother   => ( is => 'ro', isa => t('Horsey') );\nhas children => ( is => 'ro', isa => t('ArrayRef[Horsey]') );\n...;\n}\n\nYou don't even need to import the \"t()\" function. Types::Registry can be used in an entirely\nobject-oriented way.\n\npackage Horse {\nuse Moo;\nuse Type::Registry;\n\nmy $reg = Type::Registry->forme;\n\n$reg->addtypes('-Standard');\n$reg->addtypes('-Common::String');\n$reg->addtypes('-Common::Numeric');\n\n$reg->aliastype('InstanceOf[\"Horse\"]' => 'Horsey');\n\nhas name => ( is => 'ro', isa => $reg->lookup('Str') );\n...;\n}\n\nYou could create two registries with entirely different definitions for the same named type.\n\nmy $dracula = Aristocrat->new(name => 'Dracula');\n\npackage AristocracyTracker {\nuse Type::Registry;\n\nmy $reg1 = Type::Registry->new;\n$reg1->addtypes('-Common::Numeric');\n$reg1->aliastype('PositiveInt' => 'Count');\n\nmy $reg2 = Type::Registry->new;\n$reg2->addtypes('-Standard');\n$reg2->aliastype('InstanceOf[\"Aristocrat\"]' => 'Count');\n\n$reg1->lookup(\"Count\")->assertvalid(\"1\");\n$reg2->lookup(\"Count\")->assertvalid($dracula);\n}\n\nType::Registry uses \"AUTOLOAD\", so things like this work:\n\n$reg->ArrayRef->of( $reg->Int );\n\nAlthough you can create as many registries as you like, Type::Registry will create a default\nregistry for each package.\n\n# Create a new empty registry.\n#\nmy $reg = Type::Registry->new;\n\n# Get the default registry for my package.\n# It will be pre-populated with any types we imported using `use`.\n#\nmy $reg = Type::Registry->forme;\n\n# Get the default registry for some other package.\n#\nmy $reg = Type::Registry->forclass(\"Horse\");\n\nType registries are a convenient place to store a bunch of types without polluting your\nnamespace. They are not the same as type libraries though. Types::Standard,\nTypes::Common::String, and Types::Common::Numeric are type libraries; packages that export types\nfor others to use. We will look at how to make one of those later.\n\nFor now, here's the best way to think of the difference:\n\n*   Type registry\n\nCurate a collection of types for me to use here in this class. This collection is an\nimplementaion detail.\n\n*   Type library\n\nExport a collection of types to be used across multiple classes. This collection is part of\nyour API.\n"
                    },
                    {
                        "name": "Importing Functions",
                        "content": "We've seen how, for instance, Types::Standard exports a sub called \"Int\" that returns the Int\ntype object.\n\nuse Types::Standard qw( Int );\n\nmy $type = Int;\n$type->check($value) or die $type->getmessage($value);\n\nType libraries are also capable of exporting other convenience functions.\n\n\"is*\"\nThis is a shortcut for checking a value meets a type constraint:\n\nuse Types::Standard qw( isInt );\n\nif ( isInt($value) ) {\n...;\n}\n\nCalling \"isInt($value)\" will often be marginally faster than calling \"Int->check($value)\"\nbecause it avoids a method call. (Method calls in Perl end up slower than normal function\ncalls.)\n\nUsing things like \"isArrayRef\" in your code might be preferable to \"ref($value) eq \"ARRAY\"\"\nbecause it's neater, leads to more consistent type checking, and might even be faster.\n(Type::Tiny can be pretty fast; it is sometimes able to export these functions as XS subs.)\n\nIf checking type constraints like \"isArrayRef\" or \"isInstanceOf\", there's no way to give a\nparameter. \"isArrayRef[Int]($value)\" doesn't work, and neither does \"isArrayRef(Int, $value)\"\nnor \"isArrayRef($value, Int)\". For some types like \"isInstanceOf\", this makes them fairly\nuseless; without being able to give a class name, it just acts the same as \"isObject\". See\n\"Exporting Parameterized Types\" for a solution. Also, check out isa.\n\nThere also exists a generic \"is\" function.\n\nuse Types::Standard qw( ArrayRef Int );\nuse Type::Utils qw( is );\n\nif ( is ArrayRef[Int], \\@numbers ) {\n...;\n}\n\n\"assert*\"\nWhile \"isInt($value)\" returns a boolean, \"assertInt($value)\" will throw an error if the value\ndoes not meet the constraint, and return the value otherwise. So you can do:\n\nmy $sum = assertInt($x) + assertInt($y);\n\nAnd you will get the sum of integers $x and $y, and an explosion if either of them is not an\ninteger!\n\nAssert is useful for quick parameter checks if you are avoiding Type::Params for some strange\nreason:\n\nsub addnumbers {\nmy $x = assertNum(shift);\nmy $y = assertNum(shift);\nreturn $x + $y;\n}\n\nYou can also use a generic \"assert\" function.\n\nuse Type::Utils qw( assert );\n\nsub addnumbers {\nmy $x = assert Num, shift;\nmy $y = assert Num, shift;\nreturn $x + $y;\n}\n\n\"to*\"\nThis is a shortcut for coercion:\n\nmy $truthy = toBool($value);\n\nIt trusts that the coercion has worked okay. You can combine it with an assertion if you want to\nmake sure.\n\nmy $truthy = assertBool(toBool($value));\n\nShortcuts for exporting functions\nThis is a little verbose:\n\nuse Types::Standard qw( Bool isBool assertBool toBool );\n\nIsn't this a little bit nicer?\n\nuse Types::Standard qw( +Bool );\n\nThe plus sign tells a type library to export not only the type itself, but all of the\nconvenience functions too.\n\nYou can also use:\n\nuse Types::Standard -types;   # export Int, Bool, etc\nuse Types::Standard -is;      # export isInt, isBool, etc\nuse Types::Standard -assert;  # export assertInt, assertBool, etc\nuse Types::Standard -to;      # export toBool, etc\nuse Types::Standard -all;     # just export everything!!!\n\nSo if you imagine the functions exported by Types::Standard are like this:\n\nqw(\nStr             isStr          assertStr\nNum             isNum          assertNum\nInt             isInt          assertInt\nBool            isBool         assertBool     toBool\nArrayRef        isArrayRef     assertArrayRef\n);\n# ... and more\n\nThen \"+\" exports a horizonal group of those, and \"-\" exports a vertical group.\n"
                    },
                    {
                        "name": "Exporting Parameterized Types",
                        "content": "It's possible to export parameterizable types like ArrayRef, but it is also possible to export\n*parameterized* types.\n\nuse Types::Standard qw( ArrayRef Int );\nuse Types::Standard (\n'+ArrayRef' => { of => Int, -as => 'IntList' },\n);\n\nhas numbers => (is => 'ro', isa => IntList);\n\nUsing \"isIntList($value)\" should be significantly faster than\n\"ArrayRef->of(Int)->check($value)\".\n\nThis trick only works for parameterized types that have a single parameter, like ArrayRef,\nHashRef, InstanceOf, etc. (Sorry, \"Dict\" and \"Tuple\"!)\n\nDo What I Mean!\nuse Type::Utils qw( dwimtype );\n\ndwimtype(\"ArrayRef[Int]\")\n\n\"dwimtype\" will look up a type constraint from a string and attempt to guess what you meant.\n\nIf it's a type constraint that you seem to have imported with \"use\", then it should find it.\nOtherwise, if you're using Moose or Mouse, it'll try asking those. Or if it's in\nTypes::Standard, it'll look there. And if it still has no idea, then it will assume"
                    },
                    {
                        "name": "dwim_type",
                        "content": "It just does a big old bunch of guessing.\n\nThe \"is\" function will use \"dwimtype\" if you pass it a string as a type.\n\nuse Type::Utils qw( is );\n\nif ( is \"ArrayRef[Int]\", \\@numbers ) {\n...;\n}\n"
                    }
                ]
            },
            "NEXT STEPS": {
                "content": "You now know pretty much everything there is to know about how to use type libraries.\n\nHere's your next step:\n\n*   Type::Tiny::Manual::Libraries\n\nDefining your own type libraries, including extending existing libraries, defining new\ntypes, adding coercions, defining parameterizable types, and the declarative style.\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": []
            }
        }
    }
}