{
    "content": [
        {
            "type": "text",
            "text": "# Type::Tiny::Manual::Libraries (perldoc)\n\n## NAME\n\nType::Tiny::Manual::Libraries - defining your own type libraries\n\n## Sections\n\n- **NAME**\n- **MANUAL** (7 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::Libraries",
        "section": "",
        "mode": "perldoc",
        "summary": "Type::Tiny::Manual::Libraries - defining your own type libraries",
        "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": "Defining a Type",
                        "lines": 44
                    },
                    {
                        "name": "Defining a Library",
                        "lines": 122
                    },
                    {
                        "name": "Extending Libraries",
                        "lines": 41
                    },
                    {
                        "name": "Custom Error Messages",
                        "lines": 26
                    },
                    {
                        "name": "Inlining",
                        "lines": 78
                    },
                    {
                        "name": "Pre-Declaring Types",
                        "lines": 19
                    },
                    {
                        "name": "Parameterizable Types",
                        "lines": 63
                    }
                ]
            },
            {
                "name": "NEXT STEPS",
                "lines": 8,
                "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::Libraries - defining your own type libraries\n",
                "subsections": []
            },
            "MANUAL": {
                "content": "",
                "subsections": [
                    {
                        "name": "Defining a Type",
                        "content": "A type is an object and you can create a new one using the constructor:\n\nuse Type::Tiny;\n\nmy $type = Type::Tiny->new(%args);\n\nA full list of the available arguments can be found in the Type::Tiny documentation, but the\nmost important ones to begin with are:\n\n\"name\"\nThe name of your new type. Type::Tiny uses a convention of UpperCamelCase names for type\nconstraints. The type name may also begin with one or two leading underscores to indicate a\ntype intended for internal use only. Types using non-ASCII characters may cause problems on\nolder versions of Perl (pre-5.8).\n\nAlthough this is optional and types may be anonymous, a name is required for a type\nconstraint to added to a type library.\n\n\"constraint\"\nA code reference checking $ and returning a boolean. Alternatively, a string of Perl code\nmay be provided.\n\nIf you've been paying attention, you can probably guess that the string of Perl code may\nresult in more efficient type checks.\n\n\"parent\"\nAn existing type constraint to inherit from. A value will need to pass the parent constraint\nbefore its own constraint would be called.\n\nmy $Even = Type::Tiny->new(\nname       => 'EvenNumber',\nparent     => Types::Standard::Int,\nconstraint => sub {\n# in this sub we don't need to check that $ is an Int\n# because the parent will take care of that!\n\n$ % 2 == 0\n},\n);\n\nAlthough the \"parent\" is optional, it makes sense whenever possible to inherit from an\nexisting type constraint to benefit from any optimizations or XS implementations they may\nprovide.\n"
                    },
                    {
                        "name": "Defining a Library",
                        "content": "A library is a Perl module that exports type constraints as subs. Types::Standard,\nTypes::Common::Numeric, and Types::Common::String are type libraries that are bundled with\nType::Tiny.\n\nTo create a type library, create a package that inherits from Type::Library.\n\npackage MyTypes {\nuse Type::Library -base;\n\n...; # your type definitions go here\n}\n\nThe \"-base\" flag is just a shortcut for:\n\npackage MyTypes {\nuse Type::Library;\nour @ISA = 'Type::Library';\n}\n\nYou can add types like this:\n\npackage MyTypes {\nuse Type::Library -base;\n\nmy $Even = Type::Tiny->new(\nname       => 'EvenNumber',\nparent     => Types::Standard::Int,\nconstraint => sub {\n# in this sub we don't need to check that $ is an Int\n# because the parent will take care of that!\n\n$ % 2 == 0\n},\n);\n\nPACKAGE->addtype($Even);\n}\n\nThere is a shortcut for adding types if they're going to be blessed Type::Tiny objects and not,\nfor example, a subclass of Type::Tiny. You can just pass %args directly to \"addtype\".\n\npackage MyTypes {\nuse Type::Library -base;\n\nPACKAGE->addtype(\nname       => 'EvenNumber',\nparent     => Types::Standard::Int,\nconstraint => sub {\n# in this sub we don't need to check that $ is an Int\n# because the parent will take care of that!\n\n$ % 2 == 0\n},\n);\n}\n\nThe \"addtype\" method returns the type it just added, so it can be stored in a variable.\n\nmy $Even = PACKAGE->addtype(...);\n\nThis can be useful if you wish to use $Even as the parent type to some other type you're going\nto define later.\n\nHere's a bigger worked example:\n\npackage Example::Types {\nuse Type::Library -base;\nuse Types::Standard -types;\nuse DateTime;\n\n# Type::Tiny::Class is a subclass of Type::Tiny for creating\n# InstanceOf-like types. It's kind of better though because\n# it does cool stuff like pass through $type->new(%args) to\n# the class's constructor.\n#\nmy $dt = PACKAGE->addtype(\nType::Tiny::Class->new(\nname    => 'Datetime',\nclass   => 'DateTime',\n)\n);\n\nmy $dth = PACKAGE->addtype(\nname    => 'DatetimeHash',\nparent  => Dict[\nyear       => Int,\nmonth      => Optional[ Int ],\nday        => Optional[ Int ],\nhour       => Optional[ Int ],\nminute     => Optional[ Int ],\nsecond     => Optional[ Int ],\nnanosecond => Optional[ Int ],\ntimezone  => Optional[ Str ],\n],\n);\n\nmy $eph = PACKAGE->addtype(\nname    => 'EpochHash',\nparent  => Dict[ epoch => Int ],\n);\n\n# Can't just use \"pluscoercions\" method because that creates\n# a new anonymous child type to add the coercions to. We want\n# to add them to the type which exists in this library.\n#\n$dt->coercion->addtypecoercions(\nInt,    q{ DateTime->fromepoch(epoch => $) },\nUndef,  q{ DateTime->now() },\n$dth,   q{ DateTime->new(%$) },\n$eph,   q{ DateTime->fromepoch(%$) },\n);\n\nPACKAGE->makeimmutable;\n}\n\n\"makeimmutable\" freezes to coercions of all the types in the package, so no outside code can\ntamper with the coercions, and allows Type::Tiny to make optimizations to the coercions, knowing\nthey won't later be altered. You should always do this at the end.\n\nThe library will export types Datetime, DatetimeHash, and EpochHash. The Datetime type will have\ncoercions from Int, Undef, DatetimeHash, and EpochHash.\n"
                    },
                    {
                        "name": "Extending Libraries",
                        "content": "Type::Utils provides a helpful function \"extends\".\n\npackage My::Types {\nuse Type::Library -base;\nuse Type::Utils qw( extends );\n\nBEGIN { extends(\"Types::Standard\") };\n\n# define your own types here\n}\n\nThe \"extends\" function (which you should usually use in a \"BEGIN { }\" block not only loads\nanother type library, but it also adds all the types from it to your library.\n\nThis means code using the above My::Types doesn't need to do:\n\nuse Types::Standard qw( Str );\nuse My::Types qw( Something );\n\nIt can just do:\n\nuse My::Types qw( Str Something );\n\nBecause all the types from Types::Standard have been copied across into My::Types and are also\navailable there.\n\n\"extends\" can be passed a list of libraries; you can inherit from multiple existing libraries.\nIt can also recognize and import types from MooseX::Types, MouseX::Types, and Specio::Exporter\nlibraries.\n\nSince Type::Library 1.012, there has been a shortcut for \"extends\".\n\npackage My::Types {\nuse Type::Library -extends => [ 'Types::Standard' ];\n\n# define your own types here\n}\n\nThe \"-extends\" flag takes an arrayref of type libraries to extend. It automatically implies\n\"-base\" so you don't need to use both.\n"
                    },
                    {
                        "name": "Custom Error Messages",
                        "content": "A type constraint can have custom error messages. It's pretty simple:\n\nType::Tiny->new(\nname       => 'EvenNumber',\nparent     => Types::Standard::Int,\nconstraint => sub {\n# in this sub we don't need to check that $ is an Int\n# because the parent will take care of that!\n\n$ % 2 == 0\n},\nmessage   => sub {\nsprintf '%s is not an even number', Type::Tiny::dd($);\n},\n);\n\nThe message coderef just takes a value in $ and returns a string. It may use\n\"Type::Tiny::dd()\" as a way of pretty-printing a value. (Don't be put off by the underscore in\nthe function name. \"dd()\" is an officially supported part of Type::Tiny's API now.)\n\nYou don't have to use \"dd()\". You can generate any error string you like. But \"dd()\" will help\nyou make undef and the empty string look different, and will pretty-print references, and so on.\n\nThere's no need to supply an error message coderef unless you really want custom error messages.\nThe default sub should be reasonable.\n"
                    },
                    {
                        "name": "Inlining",
                        "content": "In Perl, sub calls are relatively expensive in terms of memory and CPU use. The PositiveInt type\ninherits from Int which inherits from Num which inherits from Str which inherits from Defined\nwhich inherits from Item which inherits from Any.\n\nSo you might think that to check of $value is a PositiveInt, it needs to be checked all the way\nup the inheritance chain. But this is where one of Type::Tiny's big optimizations happens.\nType::Tiny can glue together a bunch of checks with a stringy eval, and get a single coderef\nthat can do all the checks in one go.\n\nThis is why when Type::Tiny gives you a choice of using a coderef or a string of Perl code, you\nshould usually choose the string of Perl code. A single coderef can \"break the chain\".\n\nBut these automatically generated strings of Perl code are not always as efficient as they could\nbe. For example, imagine that HashRef is defined as:\n\nmy $Defined = Type::Tiny->new(\nname       => 'Defined',\nconstraint => 'defined($)',\n);\nmy $Ref = Type::Tiny->new(\nname       => 'Ref',\nparent     => $Defined,\nconstraint => 'ref($)',\n);\nmy $HashRef = Type::Tiny->new(\nname       => 'HashRef',\nparent     => $Ref,\nconstraint => 'ref($) eq \"HASH\"',\n);\n\nThen the combined check is:\n\ndefined($) and ref($) and ref($) eq \"HASH\"\n\nActually in practice it's even more complicated, because Type::Tiny needs to localize and set $\nfirst.\n\nBut in practice, the following should be a sufficient check:\n\nref($) eq \"HASH\"\n\nIt is possible for the HashRef type to have more control over the string of code generated.\n\nmy $HashRef = Type::Tiny->new(\nname       => 'HashRef',\nparent     => $Ref,\nconstraint => 'ref($) eq \"HASH\"',\ninlined    => sub {\nmy $varname = pop;\nsprintf 'ref(%s) eq \"HASH\"', $varname;\n},\n);\n\nThe inlined coderef gets passed the name of a variable to check. This could be '$' or '$var' or\n\"$some{deep}{thing}[0]\". Because it is passed the name of a variable to check, instead of always\nchecking $, this enables very efficient checking for parameterized types.\n\nAlthough in this case, the inlining coderef is just returning a string, technically it returns a\nlist of strings. If there's multiple strings, Type::Tiny will join them together in a big \"&&\"\nstatement.\n\nAs a special case, if the first item in the returned list of strings is undef, then Type::Tiny\nwill substitute the parent type constraint's inlined string in its place. So an inlieing coderef\nfor even numbers might be:\n\nType::Tiny->new(\nname       => 'EvenNumber',\nparent     => Types::Standard::Int,\nconstraint => sub { $ % 2 == 0 },\ninlined    => sub {\nmy $varname = pop;\nreturn (undef, \"$varname % 2 == 0\");\n},\n);\n\nEven if you provide a coderef as a string, an inlining coderef has the potential to generate\nmore efficient code, so you should consider providing one.\n"
                    },
                    {
                        "name": "Pre-Declaring Types",
                        "content": "use Type::Library -base,\n-declare => qw( Foo Bar Baz );\n\nThis declares types Foo, Bar, and Baz at compile time so they can safely be used as barewords in\nyour type library.\n\nThis also allows recursively defined types to (mostly) work!\n\nuse Type::Library -base,\n-declare => qw( NumericArrayRef );\nuse Types::Standard qw( Num ArrayRef );\n\nPACKAGE->addtype(\nname     => NumericArrayRef,\nparent   => ArrayRef->of( Num | NumericArrayRef ),\n);\n\n(Support for recursive type definitions added in Type::Library 1.009000.)\n"
                    },
                    {
                        "name": "Parameterizable Types",
                        "content": "This is probably the most \"meta\" concept that is going to be covered. Building your own type\nconstraint that can be parameterized like ArrayRef or HasMethods.\n\nThe type constraint we'll build will be MultipleOf[$i] which checks that an integer is a\nmultiple of $i.\n\nPACKAGE->addtype(\nname       => 'MultipleOf',\nparent     => Int,\n\n# This coderef gets passed the contents of the square brackets.\nconstraintgenerator => sub {\nmy $i = assertInt(shift);\n# needs to return a coderef to use as a constraint for the\n# parameterized type\nreturn sub { $ % $i == 0 };\n},\n\n# optional but recommended\ninlinegenerator => sub {\nmy $i = shift;\nreturn sub {\nmy $varname = pop;\nreturn (undef, \"$varname % $i == 0\");\n};\n},\n\n# probably the most complex bit\ncoerciongenerator => sub {\nmy $i = $[2];\nrequire Type::Coercion;\nreturn Type::Coercion->new(\ntypecoercionmap => [\nNum, qq{ int($i * int(\\$/$i)) }\n],\n);\n},\n);\n\nNow we can define an even number like this:\n\nPACKAGE->addtype(\nname     => 'EvenNumber',\nparent   => PACKAGE->gettype('MultipleOf')->of(2),\ncoercion => 1,  # inherit from parent\n);\n\nNote that it is possible for a type constraint to have a \"constraint\" *and* a\n\"constraintgenerator\".\n\nBaseType          # uses the constraint\nBaseType[]        # constraintgenerator with no arguments\nBaseType[$x]      # constraintgenerator with an argument\n\nIn the MultipleOf example above, MultipleOf[] with no number would throw an error because of\n\"assertInt(shift)\" not finding an integer.\n\nBut it is certainly possible for BaseType[] to be meaningful and distinct from \"BaseType\".\n\nFor example, Tuple is just the same as ArrayRef and accepts any arrayref as being valid. But\nTuple[] will only accept arrayrefs with zero elements in them. (Just like Tuple[Any,Any] will\nonly accept arrayrefs with two elements.)\n"
                    }
                ]
            },
            "NEXT STEPS": {
                "content": "After that last example, probably have a little lie down. Once you're recovered, here's your\nnext step:\n\n*   Type::Tiny::Manual::UsingWithMoose\n\nHow to use Type::Tiny with Moose, including the advantages of Type::Tiny over built-in type\nconstraints, and Moose-specific features.\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": []
            }
        }
    }
}